ahrefs / atd

Static types for JSON APIs
Other
308 stars 53 forks source link

Add support for Go (Golang) #318

Open mjambon opened 1 year ago

mjambon commented 1 year ago

One route is via JSON Schema, but the current tools that derive Go code from JSON Schema appear to not support sum types (OneOf constructs other than pure enums). See this investigation by @parsiya.

Another route is to create an atdgo tool that would convert ATD definitions directly to Go. This is likely to produce nicer results than with JSON Schema but it's also a much bigger effort (roughly two weeks of full-time work for me).

One of the issues is how to translate sum types to Go, which doesn't have a simple and unique way of doing so. Suggestions are welcome!

tomjridge commented 1 week ago

Go's support for sum types is a little lacking, as noted. For code generation, one simple implementation of a sum type of two types T1 T2, is to have a struct with two fields, one of each type. It is hopefully guaranteed (by the generated code, as an implicit invariant) that exactly one of the fields is non null.

I would like to suggest this as a possible implementation of sum types.

Of course this is horrible, but for golang the code is quite concise, has good typing on each of the fields, and often when marshalling data to/from json you don't care overly much about the exact nature of the generated code, you just want it to have good support in the IDE, and be easy to work with. Having the implicit invariant is not the worst thing in the world.

mjambon commented 1 week ago

Thank you for the suggestion, @tomjridge.

If I understand correctly, Go's struct fields are mutable and automatically initialized with dummy values, which simplifies things in a way:

mjambon commented 1 week ago

The first step before starting an implementation of atdgo is to write down sample Go code that we want to generate for each kind of type definition. If anyone wants to help, feel free to start in this thread. For example, what's the code for a pure enum? for a list? for a struct? ...