As a (semi-)aside, the "union type" on the commonly rejected changes list is about a type with implicit conversions, which is a little different from the anonymous-but-explicit enum/union/sum types advocated by Pointfree and others. I wish I could find a citation for how they'd complicate the type system, but I can't, although there's a little discussion way back in an early thread about Result and Either.
TypeScript's union types allow accessing members common to all parts of the union. Swift is unlikely to support that because the low-level calling conventions for different types don't match up, and besides, Swift doesn't consider two methods with the same name to be "basically the same operation" unless they're on types conforming to the same protocol.
Ceylon's union types don't allow accessing any members ad hoc, but do allow converting to a supertype of all members. (That is, UIScrollView | UITableView
can be converted to UIView
.) This can still have strange behavior when interacting with Swift's generics: if I have an [Int] | Set<Int>
value, and I pass it to a function that takes any Collection via generic parameter and returns an index, what's the type of the result? Or is that just not allowed?
Even if your anonymous enum/union/sum type requires explicit deconstruction (i.e. "you have to pattern-match it to do anything"), there's still the question of whether you'd allow implicit conversions to the type. Even that adds additional complication in Swift's type system, though, which allows inferring types across an entire expression. While Swift's type checker has gotten a lot better over the last five years, implicit conversions are still one of the ways to make it do exponentially more work if we're not careful how it's defined.
There may also be additional complications I haven't thought of; maybe one of the type system folks will know what John and Chris were referring to in those early comments about "massively complicated the type system". But I'm pretty confident that the explicit form where you say .0(x)
and match against case .0(let value)
don't hit any of those problems. (Whether or not they're worth it is a different question.)