> On Sep 5, 2017, at 5:19 PM, Jordan Rose via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> I've taken everyone's feedback into consideration and written this up as a 
> proposal: 
> https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md
>  
> <https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md>.
>  The next step is working on an implementation, but if people have further 
> pre-review comments I'd be happy to hear them.

Hi Jordan,

I apologize in advance that I haven’t followed the back and forth on this 
thread, so I’m sorry if these thoughts are duplicative:

I really would prefer to avoid introducing the notion of 
exhaustive/nonexhaustive enums into Swift, and would much prefer that such a 
thing be limited to C (which can’t express this concept already).

We’ve talked about enums many times across years, and it seems like the 
appropriate model follows the generally understood resilience model.  
Specifically, there should be three different kinds of enums, and the kind 
should affect users outside their module in different ways:

1. private/fileprivate/internal enum: cases can be added freely.  All clients 
are in the same module, so the enum is implicitly fragile, and all switches 
within the current module may therefore be exhaustive.

2. public enum (i.e., one that isn’t marked fragile): cases may be added 
freely.  Within the module that defines the enum, switches may be exhaustive.  
However, because the enum is public and non-fragile, clients outside the 
current module must be prepared for the enum to add additional cases in future 
revisions of the API, and therefore they cannot exhaustively match the cases of 
the enum.

3. fragile public enum: cases may not be added, because that would break the 
fragility guarantee.  As such, clients within or outside of hte current module 
may exhaustively match against the enum.


This approach gives a very natural user model: app developers don’t have to 
care about enum resilience until they mark an enum as public, and even then 
they only have to care about it when/if they mark an enum as public.  This also 
builds on the notion of fragility - something we need for other nominal types 
like structs and classes - so it doesn’t introduce new language complexity.  
Also such an approach is entirely source compatible with Swift 3/4, which 
require defaults (this isn’t an accident, it follows from the anticipated 
design).

This approach doesn’t address the problem of what to do with C though, because 
C doesn’t have a reasonable notion of “extensible” vs “nonextensible” enum.  As 
such, we definitely do need an attribute (or something) to add to Clang.  I 
think that your proposal for defaulting to “extensible” and using 
__attribute__((enum_extensibility(closed))) override this is perfectly sensible.

-Chris




_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to