4 ms·
> Go’s type system allows preventing both issues in a rather elegant way. Proper enums would be elegant, not this.
by davidkunz 3y ago
> Go’s type system allows preventing both issues in a rather elegant way.
Proper enums would be elegant, not this.
- masklinn 3y agoSome way to define a closed set of values anyway. It doesn't even need to be classic-style sum types, for instance as support for generics Go introduced support for union types (I don't think they have a name?) e.g. type Foo interface { A | B | C } and the interface type is the union of those type-sets. Such interfaces can not currently be used outside of type constraints, but if that is relaxed, and type switches are updated to support and enforce exhaustive matching (and understand such sealed / nominative interfaces), you've got all the bits you need. You'd need to newtype variants to add payloads of similar underlying type e.g. `int | int`, but that's not a huge imposition, and the variants being types themselves is often convenient so it's a 50:50 tradeoff compared to classic sum type (where constructors disambiguate all variants but are not themselves types).
- foldr 3y agoAgreed. A slight wart is that default initialization would require either boxing or a somewhat arbitrary decision about which variant should be the default. So if you have e.g. var foo interface{ A | B } then foo either has to be boxed (so the default value is a nil interface) or unboxed and arbitrarily initialized as an A or a B.
- masklinn 3y agoTo me it would make sense that this be implemented as a normal interface at least initially, it would reuse all the existing bits of the language as is. Note that whether an interface boxes depends on escaping. I don't see how unboxing would have to be "arbitrarily initialized as an A or a B" either. Even with a novel bespoke implementation you still need a discriminant between the two nested. You could keep a nil default by reserving the zero discriminant for that purpose.
- foldr 3y agoI agree with your first paragraph. I think it would be weird if an unboxed union of A and B was initialized to a value that wasn't the default value of either A or B, although I take your point that it's a technically possible implementation.
- masklinn 3y ago> I don't quite understand the second one (is 'boxing' supposed to be 'unboxing'?) Yep, fixed, sorry about that. > I think it would be weird if an unboxed union of A and B was initialized to a value that wasn't the default value of either A or B On the one hand yes, on the other hand it would be consistent with the langage semantics (the default value of an interface type is a nil), and I don’t think defaulting to the default value of an arbitrary variant is better. Although I can see the similarity with iota / newtype constants, the first item being the default, and similarly people could set the first type as relevantly named (possibly unexported) empty struct if they want / need the signal.