ahrefs/atd

Add support for Go (Golang)

mjambon opened this issue · 3 comments

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!

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.

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:

  • Constructing a case doesn't require initializing a bunch of fields. It can be done concisely by setting just two fields. The code generator would provide a function to create each case with slightly more type safety but the user wouldn't have to use it.
  • Reading a value doesn't require dealing with unwrapping an optional field since no field is optional (all but one would be set to a dummy value, though).

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? ...