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 <[email protected]> wrote:
>
>> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution
>> <[email protected]> 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
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution