5 ms·
Eh, that's a tagged union, but I think "union type" usually refers to untagged unions like you see in more dynamic languages such as TypeScript and Facebook's F
by tree_of_item 12y ago
Eh, that's a tagged union, but I think "union type" usually refers to untagged unions like you see in more dynamic languages such as TypeScript and Facebook's Flow. Tagged unions are typically called sum types. That is, searching for "union type" is gonna give you results about untagged unions or C style unions. I'm not sure this new terminology helps.
- johnpmayer 12y agoFor the record, I voted for enum, like in rust-lang ;-) This was going to be contentious no matter what. For what it's worth, Wikipedia (top Google result) seems to have a compatible story. Luckily, it's just a conversation change. I think it will be fine, and net more helpful than damaging. The overall goals are intuition and accessibility.
- kibwen 12y ago> For the record, I voted for enum, like in rust-lang ;-) Funny, because there's actually a long, long history of debate around whether Rust should refer to them as unions rather than enums (and change the keyword correspondingly). :) Here's the most recent one that I know of: https://github.com/rust-lang/rfcs/pull/27 https://github.com/rust-lang/rfcs/pull/27 Swift seems to have followed Rust's example with its terminology here, so this issue is hardly settled. It may shake out such that `enum` is used for tagged unions where the variants are declared as part of the type (`enum Foo { Bar, Baz}`) (and hence the variants can't be shared between types, at least not without wrapping in a newly-defined variant), whereas `union` is used for tagged unions where the type is composed from multiple existing types (`type Bar; type Baz; union Foo { Bar | Baz }`).
- brandonbloom 12y agoDepending on who you ask, there's another established meaning of "union type" when contrasting it against "sum type" in a safe context. Sum types are discriminated unions in which each constructor tag in the union is disjoint from each other member and all other types. In contrast, "union type" tends to imply that you can share constructors/tags between types. For example Julia: http://docs.julialang.org/en/release-0.3/manual/types/#type-unions http://docs.julialang.org/en/release-0.3/manual/types/#type-... Typed Racket: http://docs.racket-lang.org/ts-guide/beginning.html#%28part._.Datatypes_and_.Unions%29 http://docs.racket-lang.org/ts-guide/beginning.html#%28part.... Haskell: http://okmij.org/ftp/Haskell/extensible/#open-union http://okmij.org/ftp/Haskell/extensible/#open-union And many more.
- tree_of_item 12y agoThis is precisely what I was describing, perhaps I wasn't clear enough. I should have mentioned Typed Racket as well. Unless you think this is different from what I said? Typed Racket's unions are just like TypeScript and Flow's unions, in fact TypeScript uses a similar occurrence typing algorithm where you need to do a type check in order to compute with a union value, e.g. if (isString(x)) { // only now can we call string functions on x } else if (isNumber(x)) { // only now can we call number functions on x }
- brandonbloom 12y agoOK, then we're on the same page regarding Elm's name choice: That is, it's a poor choice if they are actually disjoint unions aka sum types. That said, forgive me pedantry for a moment: I think your use of the word "tag" is unclear. Typically, both sum types and union types must be tagged. If you think about something like the JVM, every object is tagged with a pointer to it's class. Untagged, or "tagless", objects are closely related to "unboxed" objects, but still not quite the same thing. The point is that the tag is something that can be inspected, switched on, etc at runtime. Where as a tagless representation does not require that runtime overhead. It's possible to have a Union(int, String) or something like that where one type is typically untagged and the other typically tagged. If the compiler could eliminate the tag at runtime from context, then it would just eliminate the union and substitute the type with either int or String directly. So if it can't tell from context, it must actually make it a Union(Box<int>, String) so it can discriminate by tag. Tangential: There is of course a trade off in tagless representations in terms of type system complexity and runtime cost. If you want to change from a List<int> (specialized list of machine ints) to a List<Integer> (nullable boxed ints), that's an O(N) operation to add the tags (and a more complex type system).
- jmite 12y agoThe thing is, "sum types" really only works if you're familiar with the analogy between boolean algebra and arithmetic (why OR becomes +). Yes, they are disjoint union, but there's really no such thing as non-disjoint union in a statically typed language i.e. that's what makes it typesafe.
- wheatBread 12y agoWe discussed this to death on the mailing list, and this was definitely a consideration! People searching for it online will very likely be searching for "elm union type" where they'll quickly find examples and docs. Furthermore, you can prefix the term "union type" with stuff like "closed/open" and "tagged/untagged" to start making finer grained distinctions as need higher degrees of precision. In Elm it is always tagged and closed, so in discussions within the community, adding those prefixes is redundant. Finally, if you start with the term "union type" it becomes easier to think about what an "anonymous union type" might look like (like OCaml's polymorphic variants or open variants) ;) More broadly, if people do run into the term "union type" in other languages they will be building intuition in exactly the way I'd like: it's a way to use different types in the same place. Things happen to have this extra tag thing in Elm, but it's not so different than anything people do in JS or Clojure or Racket or TypeScript or C or whatever else. I think bringing that connection out is a major benefit of this naming choice. The goal is to feel really welcoming and friendly, and my personal preference is to build on people's existing intuition as much as possible. If someone comes from JS and does not see all the subtleties of this discussion immediately on day one, they are actually having a better experience because they can learn the info as it becomes relevant to their daily usage. Hopefully a much nicer learning curve! I realize I am making a somewhat controversial choice, but the idea is that statically typed FP people are building artificial barriers by being sticklers about this, rather than just prefixing for precision. You may not agree with all this, but we thought it through pretty extensively, and that is the reasoning!