Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 8:13 PM, Jonathan Hull  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  wrote:
>> 
>>> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>>>  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
>>>  

Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread Jonathan Hull via swift-evolution
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  wrote:
> 
>> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>>  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]
>> 
>> 

Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread Matthew Johnson via swift-evolution

> On Aug 18, 2017, at 2:19 PM, Adrian Zubarev  
> wrote:
> 
> Wasn’t Joe Groff and Daniel Duan proposing anonymous enum cases in some of 
> the early draft of the ‘Normalize Enum Case Representation’ proposal? 
> 
> Maybe it’s time to revive that topic.
> 
> Matthew Johnson has also some interesting ideas in hist gist: 
> https://gist.github.com/anandabits/5b7f8e3836387e893e3a1197a4bf144d#structural-unions
>  
> As
>  far as I know that turns out to be equivalent to the commonly rejected 
> feature.  :)
> 
> 
> 
> 
> Am 18. August 2017 um 21:08:22, Robert Bennett via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> The better solution would be to allow the creation of new enums from the 
>> union of existing enums, which was proposed recently.
>> 
>> On Aug 18, 2017, at 2:36 PM, John McCall via swift-evolution 
>> > wrote:
>> 
>> >> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>> >> > 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 
>> 

Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread Adrian Zubarev via swift-evolution
Wasn’t Joe Groff and Daniel Duan proposing anonymous enum cases in some of the 
early draft of the ‘Normalize Enum Case Representation’ proposal?

Maybe it’s time to revive that topic.

Matthew Johnson has also some interesting ideas in hist gist: 
https://gist.github.com/anandabits/5b7f8e3836387e893e3a1197a4bf144d#structural-unions




Am 18. August 2017 um 21:08:22, Robert Bennett via swift-evolution 
(swift-evolution@swift.org) schrieb:

The better solution would be to allow the creation of new enums from the union 
of existing enums, which was proposed recently.

On Aug 18, 2017, at 2:36 PM, John McCall via swift-evolution 
 wrote:

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

Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread Robert Bennett via swift-evolution
The better solution would be to allow the creation of new enums from the union 
of existing enums, which was proposed recently.

On Aug 18, 2017, at 2:36 PM, John McCall via swift-evolution 
 wrote:

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


Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>  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


[swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread Jonathan Hull via swift-evolution

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.

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