3 ms·
> The standard implementation is pretty simple: the different variants of a sum have a tag that tells the runtime which variant they are, and hence where to fin
by klodolph 2y ago
> The standard implementation is pretty simple: the different variants of a sum have a tag that tells the runtime which variant they are, and hence where to find pointers.
That won’t work in Go, because it would not be safe. You would need to coordinate the change with the concurrent garbage collector. It’s not designed to do this. Redesigning it to do this would be non-trivial.
Go already has a lesser-known safety problem similar to this involving interface types, but that safety problem is at least avoidable if you write code without data races in it. With the union safety problem, the data race is harder to avoid.
- foldr 2y agoAs parent mentions, Go already does exactly this for interface values, so the problem has already been solved. This is at most a problem if you want to avoid boxing individual union variants. Otherwise, the runtime representation of a union can just be an interface value (with some extra type system stuff to enforce exhaustive matching, etc. etc.) Previous discussion here: https://news.ycombinator.com/item?id=42305999 https://news.ycombinator.com/item?id=42305999
- yencabulator 2y agoInterface type implementation was explicitly changed to not trigger this problem. Now small values cannot be stored inline in the interface, where they can be confused for pointers. All things stored in interfaces have to be allocated, and the GC associates "what parts are pointers" with the memory location, not with the interface type tag.
- foldr 2y agoYes, that's true. But that means the problem is solved, no? I think my previous comment was badly worded. I just meant to say that Go has a concurrent GC and a runtime representation of a value that can instantiate one of a number of different types (i.e. interface values). So as long as one is willing to accept that as an implementation for an enum/union type, all of the major runtime problems are already solved.
- yencabulator 2y agoGrandparent tried to argue that the mere existence of a tag tells GC what to do, when that's racy. If you avoid the race, forcing sum types to only ever contain a single pointer, sure that avoids the race too. It still doesn't get you a meaningful zero value, which the language design assumes to exist for every type.
- foldr 2y agoSure, I appreciate that concurrent GCs are hard. For interfaces, the Go team chose one of a number of possible solutions: https://github.com/golang/go/issues/8405 https://github.com/golang/go/issues/8405 If the language were to add support for union types, these tradeoffs could potentially be revisited. Other commentators have pointed out that nil is a perfectly good default value for a union (if it's underlyingly an interface).