3 ms·
Sure, but "the same as Rust's enums" including a mention of pattern matching, is a really big expenditure on the novelty budget from the point of view of Go. Wh
by tialaramex 2y ago
Sure, but "the same as Rust's enums" including a mention of pattern matching, is a really big expenditure on the novelty budget from the point of view of Go. What Rust does there is perfectly normal... for an ML. But before Rust you didn't really see an ML down there counting CPU cycles, so this wasn't even on the radar when Go was invented.
I think to do that you'd probably give up a lot of the simplicity Go is aiming for. I personally think that simplicity is somewhat illusion (Amos' "I want off Mr. Golang's Wild Ride" https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-... says it better than I could) but we should be clear that it's not that Go aimed to do what I want and missed but that it was never interested in that at all. An F1 car doesn't want to be useful for taking the kids to school, so it's silly if we're scoring it poorly for lack of child seat fixtures.
- masklinn 2y ago> Sure, but "the same as Rust's enums" including a mention of pattern matching, is a really big expenditure on the novelty budget from the point of view of Go. Following the addition of type sets for generics I think go actually has all the pieces for union types already and it’s a matter of putting them all together at the compiler level: - allow type sets as types (currently they’re only valid for constraints), probably excluding those using “underlying types” - implement match completeness for type switches over type sets And there you go, you’ve got unions from which you can easily implement sums via type declarations: type Foo int type Bar struct {} type FooOrBar interface { Foo | Bar } func Thing(v FooOrBar) { switch vv := v.(type) { case Foo: // you have a foo case Bar: // you have a bar // a default case is required if the cases are not exhaustive, forbidden if they are } } Is this perfect? Not even remotely, this suffers from the usual Go issues of zero values, unenforceable constructors, and nil interfaces. But these are issues of the language, they should be fixed in the language in a hypothetical Go 2, I don’t think there is a good reason to try and work around them here. Also completeness requirements could probably be extended to all “trivial” switches (types or values, not generalised expressions) via a go.mod stricture, similar to the new loop semantics.