3 ms·
Go does have sum types — but the syntax is awkward and a bit transparent, so many don't recognize it as being there, and those that do don't love using it.
by 9rx 7mo ago
Go does have sum types — but the syntax is awkward and a bit transparent, so many don't recognize it as being there, and those that do don't love using it.
- School-Cotton 7mo agoCan you enlighten us to what you’re talking about instead of vagueposting like this? What’s the supposed way of simulating sum types in go?
- 9rx 7mo agoI am not sure how would you would simulate them. With enums and structs, I suppose? However, it also has true sum types: type SumType interface { isSumType() } type A string func (A) isSumType() type B int func (B) isSumType() But as you can see the syntax leaves a lot to be desired and may not be all that obvious to those who are hung up thinking in other languages.
- School-Cotton 7mo agointerfaces in go aren’t types, so no, that’s not a sum type, it’s just an interface. The set of objects that can fulfill that interface is not just string and int, it’s anything in the world that someone might decide to write an isSumType function for.
- 9rx 7mo ago> it’s anything in the world that someone might decide to write an isSumType function for. No. Notice the lowercase tag name. It is impossible for anyone else to add an arbitrary type to the closed set. Unless your argument is that sum types fundamentally cannot exist? Obviously given a more traditional syntax like, type SumType tagged { A | B } ...one can come along and add C just the same. I guess that is true in some natural properties of the universe way. It is a poor take in context, however.
- kbolino 7mo agoInterfaces in Go are structurally typed but they're still types. A variable of an interface type has two components: a pointer to its dynamic type information, including virtual method table, and a pointer to its value. When you consider that any compiled Go program has a finite set of known types concretely implementing each of its interfaces, they essentially become discriminated unions, albeit without Rust's compact inline representation (unless the dynamic type is itself a thin pointer).
- kbolino 7mo agoThis forms a closed set of types (A, B, nil -- don't forget nil!) but the compiler doesn't understand it as such and complains that the following type-switch is not exhaustive ("missing return"): func Foo(s SumType) bool { switch s.(type) { case A: return true case B: return true case nil: return true } } Also, you, the package author, may know what constitutes SumType, but the consumers of your package don't, at least not without source. Moreover, you can spread A, B, and any other implementations of SumType across many source files, making it hard to answer the question even with source. This is even a problem for the standard library, just consider go/ast and its Decl, Expr, and Stmt interfaces, none of which document what types actually implement them.
- 9rx 7mo ago> but the compiler doesn't understand ... Right — While it does has sum types, it doesn't have some other features found in other languages. But, of course, if one wanted those features they would talk about those features. In this discussion, we're talking specifically about sum types, which Go most definitely does have. > nil -- don't forget nil! This is why alternative syntax has never been added. Nobody can figure out how to eliminate nil or make it clear that nil is always part of the set in a way that improves upon the current sum types.