> The function is in the `encoding/json/v2` package. It might have a similar design, and maybe they will use the same function signature for other encoders, but it the functions are very much json specific.
But the point you keep missing is that the function signature needs to be encoder agnostic for it to work as an interface. That’s a hard requirement.
And since interfaces are a convenience to allow common abstractions to be reused at runtime, you cannot depend on things like generics (ie compile time abstractions) to generalise the data types for disparate serialisation formats.
I know this limitation well because I’ve built a shell with a typed pipeline and support for different serialisation formats. So make heavy use interfaces to achieve this. And I’ve spent a lot of time investigating alternative approaches. Each time, I’ve found interfaces to be a massive advantage despite any tradeoffs I end up making do to generalising a “class” (to borrow a term from OOP).
I’d honestly love to have a more sophisticated type system in Go. But that’s not a limitation in this specific instance.
> But if you use a struct that has a field that can't be marshalled, you don't get a compile error, you get a runtime SemanticError. That's the problem.
My point here was: if you know you’re creating a struct to pass to the mashaller at compile time, then you’re already going to use JSONAble fields. So it’s not an issue.
And if you don’t know what you’re passing to the mashaller a compile time, then you’re dependent on runtime checks regardless of the expressiveness of Gos type system.
I don’t disagree that Gos type system is inflexible. But in respect to this specific use case, your argument is a storm in a teacup. The type system isn’t a limiting factor here.