Thanks for the response, Kevin. Xiaodi and others covered a lot of the points I 
would make but I'll add a few notes of my own.

> On Dec 19, 2017, at 15:31, Kevin Ballard via swift-evolution 
> <> wrote:
>> On Dec 19, 2017, at 2:58 PM, Ted Kremenek < 
>> <>> wrote:
>> <>
>> What is your evaluation of the proposal?
> Overall I like it, but I have some issues.
> I’m not completely sold yet on the idea that public enums should be 
> non-exhaustive by default, as I believe every single public enum I’ve ever 
> written definitely wants to be exhaustive. I’m tempted to say that enums 
> exposed by frameworks that need to maintain future-compatibility (such as 
> Apple’s frameworks) want non-exhaustive by default, but enums exposed by 
> third-party frameworks that follow semantic versioning are likely to want 
> exhaustive by default.
> In fact, this brings to mind another difference between enums in Apple 
> frameworks and enums in third-party Swift frameworks, which is the former is 
> exclusively C-compatible enums whereas the latter is going to have a lot of 
> enums that carry associated values. I have no data to support this but I’m 
> inclined to think that it’s more likely for C-compatible enums to want to be 
> non-exhaustive than it is for enums carrying associated values to want to be 
> non-exhaustive.
> So I guess I’m saying, I want more thought put on the topic of whether enums 
> defined in Swift should actually default to non-exhaustive, and I’m now 
> leaning towards the idea that they should remain exhaustive (but Obj-C enums 
> will still default to non-exhaustive).

The main argument here for me isn't about frequency, although I like Brent and 
Sebastian's discussion about "three types of enums" (inherently exhaustive, 
non-exhaustive but useful to switch on, and things that are just inputs). 
What's most important here is that a library author who doesn't think about 
enum exhaustivity doesn't need to make a major-version release if they realize 

- they need a new case
- they meant to make the enum exhaustive

Both of these are non-source-breaking changes as currently designed. In a world 
where enums are exhaustive by default, they would both be source-breaking. This 
is similar to 'open': if a library author just does the usual thing the 
language lets you do, they don't have to worry about clients doing something 
they didn't mean to allow.

> --
> I don’t like that modules using @testable imports treat all enums as 
> exhaustive. I can see why you want to do that, but being forced to handle 
> non-exhaustive enums in unit tests seems like a valuable guard against 
> accidentally publishing non-exhaustive enums that should be exhaustive.

This one's fair and I could go either way on it, but in practice my view is the 
same as Xiaodi's that it would be more annoying than useful. You can always 
import the library without using '@testable' in a different unit test source 

> --
> I’m really not a fan of using a ‘default’ case in non-exhaustive enums. This 
> means that if new cases are added, the compiler can’t help me find my 
> switches. I’d really like to have an alternative way of saying “here’s how to 
> behave in the event of an unknown enum case” without also making that a 
> catch-all for unspecified-but-known cases. You already brought up this issue 
> in the alternatives section, where you stated
>> Ultimately I decided not to include this in the proposal with the 
>> expectation is that switches over non-exhaustive enums should be uncommon.
> But since non-exhaustive enums will be the default, I think this _will_ 
> become quite common, if for no other reason than you’re using a library 
> written by someone who forgot to mark enums as @exhaustive that really should 
> be.
> Regarding the comment that a ‘future’ case is impossible to test, so is a 
> ‘default’ case on a switch that is otherwise exhaustive. In the latter you 
> can test it by commenting out one of your existing cases. But you can do that 
> with ‘future’ too, just by renaming it to ‘default’ first.

Neither of those are tests that can be automated, though, right? I mean, I 
guess you could set up a "fallthrough if set" global or something…

My response to Jerome goes into this a bit too: I'm not totally happy with what 
we have, but I'm not yet convinced the alternatives sufficiently solve the 
problem either.

> --
> In the “Use-side” section it says that a switch without a default case will 
> produce a warning in Swift 4 mode. But in Swift 4 mode all enums are 
> exhaustive by default and the @exhaustive annotation does nothing. These two 
> things can’t both be true or else Swift 4 mode will emit warnings on switches 
> over enums that are very clearly supposed to be exhaustive enums.

The change of C enums from exhaustive to non-exhaustive will apply to Swift 4 
mode as well (and even Swift 3 mode, if that sticks around). The reason for 
this is that C enums with private cases are very broken right now: if an 
unexpected value makes its way into a switch in today's Swift, the behavior is 
undefined (as in, no guaranteed trap, no memory safety).

If reviewers or the core team object to this part of the proposal, we would 
leave C enums as 'exhaustive' in Swift 4 mode, but at least make a switch over 
them deterministically trap if an invalid value shows up.


>> Is the problem being addressed significant enough to warrant a change to 
>> Swift?
> Yes
>> Does this proposal fit well with the feel and direction of Swift?
> Yes
>> How much effort did you put into your review? A glance, a quick reading, or 
>> an in-depth study?
> A quick reading, followed by a few re-readings as I composed this email.
> -Kevin Ballard
> _______________________________________________
> swift-evolution mailing list

swift-evolution mailing list

Reply via email to