[swift-evolution] Enums and Source Compatibility

Matthew Johnson matthew at anandabits.com
Sun Sep 17 09:55:00 CDT 2017



Sent from my iPad

> On Sep 17, 2017, at 3:37 AM, Jonathan Hull via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I run into use cases like this all the time…
> 
> I think I would prefer to see those concrete cases in a subtype though:
> 
> 	enum DrinkSize {
> 		case small
> 		case medium
> 		case large
> 	}
> 
> 	enum SummerDrinkSize : DrinkSize {
> 		//Inherits DrinkSize’s cases
> 		case extraLarge
> 	}
> 
> Because it is a subtype, you could place a SummerDrinkSize anywhere you can put a DrinkSize.  As a result, all switches on it would need a default case to handle cases they hadn’t planned for. If you mark an enum with “final” then it can’t be extended and switches can be exhaustive.

You have the subtype relationship backwards here.  DrinkSize is a subtype of SummerDrinkSize.  All values of DrinkSize are also valid values of SummerDrinkSize but not vice versa.  For this reason, inheritance syntax doesn't make sense.  The syntax that makes more sense is some kind of case embedding syntax:

enum SummerDrinkSize {
		cases DrinkSize
		case extraLarge
}

> 
> In addition to inheriting the cases, a subtype would also inherit, and be able to override, methods defined on the super-type.  You could use super to call the super-type’s implementation. 

I think implementation sharing is a bad idea for value types.  Value subtyping should be conceptualized as a restricted mechanism for value-preserving implicit conversion.

> 
> It is a bigger overhaul, but I think it actually ends up being semantically simpler for the end user.  Basically, you can do the same types of things you can with classes... with the same syntax (just without the reference-type-ness).
> 
> It just so happens that this would also solve the problem of adding cases to (non-final) library enums, because switches of the enums would need to handle default/unexpected cases.  That is a very abstract/confusing problem for end users who don’t write libraries to understand though.  I think it is much easier to explain “final” as being the same as it is in classes, in that it prevents subclassing… which means you know what all the cases are.
> 
> More work (also more powerful), but semantically simpler. It just combines concepts we already know...
> 
> Thanks,
> Jon
> 
> 
>> On Sep 16, 2017, at 3:51 PM, Kenny Leung via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> Oops, forgot something:
>> 
>> "Can there be a kind of open enum where you can add new cases in extensions?”
>> 
>> I have a use case for this. I’m trying to write a database ORM with abstract API and concrete instances for different database. So I have defined:
>> 
>> open class Database {
>>    init(connectionDictionary: [ConnectionDictionaryKey:String]) {
>>         self.connectionDictionary = connectionDictionary;
>>     }
>> }
>> 
>> Where I have ConnectionDictionaryKey defined as an enum, with values like .hostName, .databaseName, .userName, .password, .databaseName, etc…
>> 
>> But concrete databases may have other options that need to be added to the connection dictionary. It would be nice if they could just extend ConnectionDictionaryKey with new cases.
>> 
>> -Kenny
>> 
>> 
>>> On Sep 16, 2017, at 3:35 PM, Kenny Leung via swift-evolution <swift-evolution at swift.org> wrote:
>>> 
>>> In general, I agree with everything in the proposal.
>>> 
>>> I’d like to propose these alternative extensions for clients:
>>> 
>>> 1) As a client of an enum, I’d like to know in the future when a new value has been added to an enum, since I may have to do something about it. How about adding the “exhaustive” keyword to be used in the switch statement? Like
>>> 
>>> exhaustive switch excuse {
>>>     case eatenByPet:
>>>         // …
>>>     case thoughtItWasDueNextWeek:
>>>         // …
>>>     default:
>>>         // …
>>> }
>>> 
>>> If exhaustive is used, there would be a warning if all cases aren’t covered *even though default exists*. This means that I as the client thought I had everything covered when I wrote this code.
>>> 
>>> As already mentioned, this makes the default case un-testable, which brings me to
>>> 
>>> 2) All non-exhaustive enums should have the pseudo value “default” that can be used just like a regular value. This would allow you to write code like:
>>> 
>>> teacher.failedToHandInHomework(excuse: .default)
>>> 
>>> which would allow you to trip the default case in any code you may write.
>>> 
>>> -Kenny
>>> 
>>> 
>>>> On Sep 13, 2017, at 12:17 PM, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
>>>> 
>>>> Proposal updated, same URL: https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md.
>>>> 
>>>> Thanks again for all the feedback so far, everyone!
>>>> Jordan
>>>> 
>>>> 
>>>>> On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.
>>>>> 
>>>>> I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.
>>>>> 
>>>>> Thanks for putting time into this!
>>>>> Jordan
>>>>> 
>>>>> 
>>>>>> On Sep 9, 2017, at 17:34, Rod Brown <rodney.brown6 at icloud.com> wrote:
>>>>>> 
>>>>>> Jordan,
>>>>>> 
>>>>>> Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?
>>>>>> 
>>>>>> - Rod
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170917/af88da6c/attachment.html>


More information about the swift-evolution mailing list