4 ms·
Here's a very go-like way to solve it. Make the union type default instantiate as the first possible type of the union. You might think this is a pretty dumb d
by lostdog 2y ago
Here's a very go-like way to solve it.
Make the union type default instantiate as the first possible type of the union. You might think this is a pretty dumb design decision that can lead to programmer error, but it meshes perfectly with the other mistakes in the language.
- jchw 2y agoHonestly, doesn't seem like it would be that bad. Presumably you could then have a static go vet check for any time you implicitly initialize a union type to the zero value, then it's roughly the same compromise as handling copies of non-copyable values.
- deleted 2y ago[deleted]
- klodolph 2y agoThe problem is that you can’t really make this work within the runtime in the way you think it would work. The runtime relies on being able to figure out where pointers and non-pointers are. When you assign to a union, you’re not just changing the value, you’re (potentially) changing which parts of it are pointers. If you just let this be, you have to redesign the runtime (significant changes). Alternatively, you could make the union store everything like it were a struct containing all variants… but that would be inefficient. These are not good options.
- noelwelsh 2y agoWhy do you think this is a problem? It's solved in other languages that have much more expressive type systems than Go and comparable or better performance. Rust is an obvious example. 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. Go already has a "type switch" for interfaces, so it must already store tags with values in some cases, which is exactly what is needed to make this work.
- aatd86 2y agoYou should be able to commute terms of an union without changing its identity. So this is not the right solution I'm afraid.
- noelwelsh 2y agoI must admit I don't understand what you are trying to say here. Perhaps there is some confusion around terminology. What OP calls union types are known in type theory as sum types, and are actually different from what type theory calls union types. Type theory union types are like set unions.
- aatd86 2y agoYou can't have the zero value of a union be the zero value of the first written term or (a | b) becomes different from (b | a).
- noelwelsh 2y agoCommutativity doesn't apply to sum types, though it does apply to union types. Here I'm using the type theory terms, not the terms used by OP. So this isn't really an issue. Zero values don't make any sense anyway. As the original comment said "You might think this is a pretty dumb design decision that can lead to programmer error, but it meshes perfectly with the other mistakes in the language."
- 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.
- noelwelsh 2y agoThis. It is either amusing or depressing to read hand-wringing from Go developers about design issues that have been solved for some 50-ish years (see [1]). It was the same with generic types. [1]: https://en.wikipedia.org/wiki/ML_(programming_language) https://en.wikipedia.org/wiki/ML_(programming_language)
- aatd86 2y agoIt's amusing and a bit bemusing to read these statements quite often. If it was truly the case, there wouldn't be any PL research anymore. :o)
- IshKebab 2y agoThere's still PL research because PL researchers are researching novel techniques like dependent types, linear types, formal verification, algebraic effects, advanced reference counting etc. They aren't researching features that ML had literally 50 years ago. Well I hope they aren't anyway. In fairness to the Go developers I don't think they ever said they were against generics; they just put off adding them for ages because they didn't have a design they liked. I imagine the same could happen with type unions - in 20 years when everyone has stopped using Go they'll come up with a reasonable design. :-D
- fire_lake 2y agoAs a dev I’m just not prepared to wait that long for features that have been proven to work elsewhere.
- aatd86 2y agoFeatures such as? Do you know how these features interact with each other? Why are we not using OCaml or standardML or even F# (which I tend to look favorably on) more widely then?
- IshKebab 2y agoFeatures such as type unions. The topic of this conversation. > Why are we not using OCaml or standardML or even F# (which I tend to look favorably on) more widely then? In my opinion there are a number of factors. I have most experience with OCaml, so on that: 1. Terrible Windows support. 2. Poor documentation. 3. An obsession with linked lists and recursion, which are great from a theoretical point of view, but abysmal from a performance point of view (and also simplicity IMO). 4. Poor syntax. The dearth of brackets and semicolons makes it very hard to visually parse. Something as simple as mismatched brackets can be very frustrating to resolve. The insistence on (a -> b -> c -> d) style function types is unnecessarily confusing. Generally when there has been a choice between academic cleverness and accessibility they've always chosen cleverness. 5. Global type inference is pretty clearly a mistake at this point. IMO part of the reason Rust is so successful is that it has taken a lot of the very good ideas from ML and basically fixed all of the above issues. Standard accessible C style syntax, but expression based and with proper ML style types. Fantastic documentation and Windows support. No linked lists to be seen. It's such a compelling design someone copied it for Go: https://borgo-lang.github.io/ https://borgo-lang.github.io/