[swift-evolution] [swift-evolution-announce] [Review] SE 0192 - Non-Exhaustive Enums

Matthew Johnson matthew at anandabits.com
Tue Jan 2 20:45:29 CST 2018

> On Jan 2, 2018, at 8:07 PM, Jordan Rose via swift-evolution <swift-evolution at swift.org> wrote:
> [Proposal: https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md <https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md>]
> Whew! Thanks for your feedback, everyone. On the lighter side of feedback—naming things—it seems that most people seem to like '@frozen', and that does in fact have the connotations we want it to have. I like it too.
> More seriously, this discussion has convinced me that it's worth including what the proposal discusses as a 'future' case. The key point that swayed me is that this can produce a warning when the switch is missing a case rather than an error, which both provides the necessary compiler feedback to update your code and allows your dependencies to continue compiling when you update to a newer SDK. I know people on both sides won't be 100% satisfied with this, but does it seem like a reasonable compromise?

I think this strikes a reasonable balance.  It allows people to continue compiling a dependency that hasn’t been updated if necessary while knowing (if they look at the compilation log) that the unknown case may be executed with their current SDK.  It is also straightforward to adopt a “treat warnings as errors” policy if desired.  It may also be possible to selectively silence or upgrade targeted warnings in the future which would also afford additional control over how these warnings are treated.

I spent some time digging through the archives tonight and found one of the examples I personally found compelling in motivating the need for this: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039512.html>.  It is Brent Royal-Gordon’s discussion of `SKPaymentTransactionState`:

> `SKPaymentTransactionState`, which tells you the status of an in-app purchase transaction, probably would have seemed like a data enum in iOS 3. After all, what states could a transaction take besides `purchasing`, `purchased`, `failed`, or `restored`? But in iOS 8, StoreKit introduced the `deferred` state to handle a new parental-approval feature. Third-party developers did not expect this and had to scramble to handle the unanticipated change.

This is a great example of an Apple-provided enum which is not likely to be declared exhaustive but for which people will have legitimate reasons to switch over.  I believe there were other good examples discussing 3rd party libraries (related to networking?) shared on the list in the past but I was unable to find them in the time I had available this evening.

> The next question is how to spell it. I'm leaning towards `unexpected case:`, which (a) is backwards-compatible, and (b) also handles "private cases", either the fake kind that you can do in C (as described in the proposal), or some real feature we might add to Swift some day. `unknown case:` isn't bad either.

I agree with this direction because it also addresses private cases.  It isn’t clear to me why `future` wouldn’t be backwards compatible while `unexpected` or `unknown` would but that isn’t a deciding factor for me.

I think `unknown` is the best option.  `unexpected` doesn’t seem right as it isn’t exactly unexpected.  When we use this keyword it is precisely because we know there may be private cases or new cases added in the future.  We are expecting to eventually come across a case we didn’t know about when writing the code.

> I too would like to just do `unknown:` or `unexpected:` but that's technically a source-breaking change:
> switch foo {
> case bar:
>   unknown:
>   while baz() {
>     while garply() {
>       if quux() {
>         break unknown
>       }
>     }
>   }
> }

The potential for source breakage here seems pretty remote.  I would be happiest if we could just accept it but this will be a relatively rarely used feature so I won’t complain if a syntactic compromise needs to be made.

> Another downside of the `unexpected case:` spelling is that it doesn't work as part of a larger pattern. I don't have a good answer for that one, but perhaps it's acceptable for now.
> I'll write up a revision of the proposal soon and make sure the core team gets my recommendation when they discuss the results of the review.

Thanks for keeping an open mind about this and listening to everyone’s feedback Jordan!  I really appreciate it.

> ---
> I'll respond to a few of the more intricate discussions tomorrow, including the syntax of putting a new declaration inside the enum rather than outside. Thank you again, everyone, and happy new year!

Happy new year to you as well!

> Jordan
> _______________________________________________
> 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/20180102/2adace51/attachment.html>

More information about the swift-evolution mailing list