It is different though. Sure, with a little bit of sugar, it can be used to make something that looks a bit like union types, but it should avoid the complexity in the type checker which caused that to be on the rejected list. In this case 'Int | String' is just sugar for '.int(Int) | .string(String)’, which creates an anonymous enum similar to the actual enum shown below.
Without the sugar, it really just is a quick way to build enums. Without the sugar, it can be used to make something that looks a bit like union types as well, but you just have to type .int(Int) | .string(String). I can do that with enums right now though: enum myType { case int(Int) case string(String) } This is just a shorthand way of quickly doing the above without giving it a name. > On Aug 18, 2017, at 11:35 AM, John McCall <rjmcc...@apple.com> wrote: > >> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution >> <swift-evolution@swift.org> wrote: >> The typed throws discussion brought me back to an old thought. >> >> I would really like to see a new structural type, similar to tuples, which >> act as an anonymous enum. These would actually be a distinct type from >> enums (not sure what to call them), in the same way that structs and tuples >> are different. They would have a very similar syntax to enums though, so >> they would be easy to learn. > > This is the commonly-rejected "Disjunctions in type constraints" feature. > > John. > >> >> There would be two major difference from enums: >> >> 1) Because they are structural, they can’t have associated functions or >> extensions >> >> 2) They can concatenate with one another freely >> >> For example: >> >> func foo( speed: .slow | .med | .fast ){ >> bar(speed: speed) >> } >> >> func bar(speed: .slow | .med | .fast | .ludicrous) { >> //but we couldn't call foo here because it doesn’t take >> .ludicrous >> } >> >> Each case is it’s own mini-type in a way. One ‘.slow’ is equivalent to any >> ‘.slow’ (even one from a regular enum). Essentially, it is a loosely bound >> group of cases, and type checking just means seeing if the list/value being >> passed is a subset of the list of possible cases. >> >> I’d also like to see sugar for quick conversion from normal Swift enums: >> >> enum Speed { >> case slow >> case med >> case fast >> } >> >> func foo(speed: Speed | .ludicrous) { >> //we can’t call any functions/extensions of Speed, just like we >> can’t call a func from int on (Int, Int) >> } >> >> In the above case, Speed gets converted via sugar to “.speed(Speed)” and >> then gets concatenated with .ludicrous. Ideally, it would have the added >> ability to truly convert to ".slow | .med | .fast | .ludicrous” when passed >> to something that doesn’t know about Speed: >> >> func foo(speed: Speed | .ludicrous) { >> switch speed { >> case .speed(let s): //Do something with the Speed value >> case .ludicrous: //Do something ludicrous >> } >> bar(speed: speed) //This can convert to pass by unwrapping >> Speed to a bag of cases >> } >> >> func bar(speed: .slow | .med | .fast | .ludicrous) { >> switch speed { >> case .slow: // >> case .med: // >> case .fast: // >> case .ludicrous: // >> } >> //We can’t reference Speed above because we just passed a bag >> of potential cases >> } >> >> >> The end result here is that in addition to building one-off enums quickly, >> it lets us concatenate and extend enums for use in a limited scope. I don’t >> know about you, but I run into the situation of “I want exactly this enum, >> but with one extra case” all the time. >> >> I don’t know if we want typed throws, but this type of quick concatability >> would be very useful for adding/merging potential errors. With the same >> sugar used on Speed above, it would also allow something similar to Union >> types, but without the most of the implementation headache that would cause. >> You can take in multiple types, and you get back something you can switch >> on to recover the type which was passed: >> >> func myFakeUnion(_ intOrStr: Int | String){ >> switch intOrStr { >> case .int(let i): //Do something with int >> case .string(let s): //Do something with string >> } >> } >> >> myFakeUnion(12) //Sugar! >> myFakeUnion(.string(“Hey”)) //This works too >> >> >> Finally, I would love to see the switch equivalent of ‘a ? b : c’ in Swift. >> I am not sure what the best syntax would be, but it would essentially work a >> bit like like a dictionary: >> >> let mph = speed ? [.slow:10, .med:35, .fast:75] >> >> >> Thanks, >> Jon >> >> >> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution