Hacker News new | ask | show | jobs
by dualogy 3144 days ago
> If Go had ADTs

In the process of hacking on my PureScript2Golang "transcompiler", I've realized that under the hood ADTs, also known as "tagged unions", will likely more often than not be represented exactly as just that: a "tag flag" and a data pointer. (Of course if all of an ADT's ctors are nullary, an enumish int will do the trick just as well --- I doubt this gains anything over interface{}-boxed 0-size struct type-defs though in reality.)

Now the natural "box"/container for this tag+content pattern in Go is the `interface{}` that can hold as 'content' any of your "constructors" (whether it be a struct or type-alias or prim type), plus your 'tag' pattern-matchings translate to Go's type-assertions. You see this also whenever ADTs are translated to JS or OOP languages, in some manner the "type" tag is carried along to be able to switch-case on.

Anyway, you can do poor-man's ADTs as per above today. The catch is that you get fewer compile-time checks (won't check for pattern exhaustiveness in your switch-cases, or illegal/impossible/invalid (as per your custom "dumb" ADT layouts) type assertions).

But anyone who's done some linked lists or devised parser ASTs in Go has written "ADTs" in this manner --- whether by intention or inadvertently =)

Personally, I don't care about Generics now that I'm aiming to generate low-level Go code for PureScript's parametric polymorphism and higher-kinded types system.. --- expressive beyond the old-school oop/imperative "generics" band-aid ;)

> That I can add interfaces implementations to structs I don’t own

Wait, did I miss out on some new feature only recently introduced? The way I parse your above statement, it sounds like you could define methods for receiver types imported from other packages, is that what you meant? Or did you simply have classical workarounds in mind, such as type-aliasing or set-the-"method"-as-a-struct's-func-typed-field?

1 comments

Can you link to your project?
Current approach: http://github.com/metaleap/gonad-corefn (to be renamed later) --- heavily in-flux, even more slow-going pretty-soon-now (long-term freelance gig coming up), but I'm committed to keep committing =) --- won't be polished in terms of docs/tests/better-commit-msgs etc until reaching a certain stage of completeness. Also about 1/3rd of the code can be ditched at some point, coming from earlier stages --- only will become fully apparent which 1/3 at a later stage of maturity as well though.

Earlier first approach, won't currently compile due to deps: http://github.com/metaleap/gonad-coreimp

Auxiliary stuff currently dumped in: http://github.com/golamb

For a fun ps2go comparison, side-by-side:

https://github.com/golamb/test-pscorefn-src/tree/master/src/... <-> https://github.com/golamb/test-pscorefn2go/tree/master/Mini --- lots to-do still =)