> On Aug 18, 2017, at 8:13 PM, Jonathan Hull <jh...@gbis.com> wrote:
> 
> 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.

I see your point, but I think this is still very solidly in a space that we've 
expressed interest in not pursuing, especially with the long chain of "wouldn't 
it be great" additions you're suggesting.

John.


> 
> 
> 
> 
>> 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

Reply via email to