"final"'s on my list of possible names! But it's not quite the same as 'final' 
for classes: "closed" only talks about what might change in the future, while 
'final'-on-a-class also states something about the class in the present: it has 
no subclasses now as well as not gaining any new ones in the future. Still, it 
could be closed enough that it ends up being the best bet.

Jordan


> On Aug 10, 2017, at 22:23, Rod Brown <rodney.bro...@icloud.com> wrote:
> 
> Hi all,
> 
> I thought I’d chime in with my own 2c…
> 
> I’d probably prefer something more like “final” and vs non-final. It’s the 
> concept we’re dancing around - can you add something to extend it?
> 
> In which case, final would allow exhaustive use, and non-final would require 
> handling the default case. Currently all Swift API would convert as “final”, 
> and all imported Obj-C API (with perhaps exceptions) would import as is and 
> require a default handling case. This negates the open vs public issue. But 
> it does also mean that it would become a manual issue inside the module to 
> mark the API as final to allow exhaustive switches, unless we say “exhaustive 
> switches allowed on internal/fileprivate/private types”.
> 
> Unsure how this plays into the web of things, though…
> 
> Thanks,
> 
> Rod
> 
> 
> 
>> On 11 Aug 2017, at 9:41 am, Jordan Rose via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>>> On Aug 10, 2017, at 13:00, David Hart <da...@hartbit.com 
>>> <mailto:da...@hartbit.com>> wrote:
>>> 
>>> 
>>> 
>>> On 10 Aug 2017, at 19:19, Jordan Rose <jordan_r...@apple.com 
>>> <mailto:jordan_r...@apple.com>> wrote:
>>> 
>>>> 
>>>> 
>>>>> On Aug 9, 2017, at 22:46, David Hart <da...@hartbit.com 
>>>>> <mailto:da...@hartbit.com>> wrote:
>>>>> 
>>>>> 
>>>>>> On 10 Aug 2017, at 02:42, Jordan Rose <jordan_r...@apple.com 
>>>>>> <mailto:jordan_r...@apple.com>> wrote:
>>>>>> 
>>>>>> :-) As you've all noted, there are some conflicting concerns for the 
>>>>>> default:
>>>>>> 
>>>>>> - Source compatibility: the existing behavior for an unannotated enum is 
>>>>>> "closed".
>>>>>> - Intuition: if you show someone an enum without an explicit annotation, 
>>>>>> they'll probably expect they can switch over it. (I'm going to say this 
>>>>>> is why Zach calls it a "sensible default".)
>>>>>> - Consistency: switches on an enum in the same module can always be 
>>>>>> exhaustive, so having it be different across modules is a bit annoying. 
>>>>>> (But 'public' already acts like this.)
>>>>>> 
>>>>>> vs.
>>>>>> 
>>>>>> - Library evolution: the default should promise less, so that you have 
>>>>>> the opportunity to change it.
>>>>>> - Flexibility: you can emulate an exhaustive switch with a 
>>>>>> non-exhaustive switch using fatalError, but not the other way around.
>>>>>> 
>>>>>> All of this is why I suggested it be an explicit annotation in either 
>>>>>> direction, but Matthew brought up the "keyword soup" problem—if you have 
>>>>>> to write (say) "public finite enum" and "public infinite enum", but 
>>>>>> would never write "private finite enum" or "private infinite enum", 
>>>>>> something is redundant here. Still, I'm uncomfortable with the default 
>>>>>> case being the one that constrains library authors, so at least for 
>>>>>> binary frameworks (those compiled "with resilience") I would want that 
>>>>>> to be explicit. That brings us to one more concern: how different should 
>>>>>> binary frameworks be from source frameworks?
>>>>> 
>>>>> In terms of intuition and consistency, I think we should really try to 
>>>>> learn from the simplicity of public/open:
>>>>> 
>>>>> * When internal, classes are sub-classable by default for convenience, 
>>>>> but can be closed with the final keyword
>>>>> * When public, classes are closed to sub-classing for safety, but can be 
>>>>> opened up with the open keyword (which implies public).
>>>>> 
>>>>> If we try to mirror this behaviour (the keywords are just suggestions, 
>>>>> not important):
>>>>> 
>>>>> * When internal, enums are exhaustive by default for convenience, but can 
>>>>> be opened-up with the partial keyword
>>>>> * When public, enums are non-exhaustive by default for safety, but can be 
>>>>> made exhaustive with the exhaustive keyword (which implies public).
>>>> 
>>>> This is not a correct understanding of the internal/public distinction for 
>>>> classes, though. From inside a module, a public-but-not-open class is 
>>>> still subclassable, and similarly a public-but-not-"closed" enum will 
>>>> still be exhaustively switched. You don't have to worry about your own 
>>>> module changing out from under you.
>>> 
>>> Correct. Thanks for the clarification! But you still agree with the 
>>> argument, right? Convenience for same module enums (exhaustive by default), 
>>> safety for clients of the module (not-exhaustive when public from outside 
>>> the module), with the option to be explicit?
>> 
>> That's the "library evolution" criterion above, yes. But the behavior of 
>> enums inside the module doesn't need to affect what we do across modules.
>> 
>>> And what do you think of the idea of having the « exhaustiveness » modifier 
>>> imply public, like open does?
>> 
>> I'm a little less sure about that. It does help with the keyword soup 
>> problem, but it's also not as obviously about access as "open" was, and 
>> "open" can also appear where other access modifiers can appear (on methods, 
>> properties, and subscripts).
>> 
>> Jordan
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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