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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 2 21:03:51 CST 2018

On Tue, Jan 2, 2018 at 8:49 PM, Matthew Johnson <matthew at anandabits.com>

> On Jan 2, 2018, at 8:45 PM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
> On Tue, 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/mas
>> ter/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?
>> 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 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
>>       }
>>     }
>>   }
>> }
>> 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.
>> ---
>> 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!
> I do like this spelling of `@frozen`, and `unknown case` looks perfectly
> cromulent to me. If this is the path to go down, I'd urge more explicit
> design as to what happens when `unknown case` and `default` are mixed. I
> would imagine the most consistent design would be:
> `unknown case` should allow `default` to be omitted if the switch is
> otherwise exhaustive, obviously.
> `default` should allow `unknown case` to be omitted, just like any other
> case may then be omitted.
> `unknown case` before `default` should be allowed, just like any other
> case before `default`; in that case, only known cases not otherwise matched
> reach the `default`.
> `default` before `unknown case` makes the latter unreachable, just like
> any other case after `default`.
> The issue here remains that of testability. I wonder if, for such
> purposes, unknown case should be instantiable when testably imported, with
> some grammar. In its simplest and yet most exotic form, we could imagine
> code that testably imports the enum to be allowed to instantiate any
> made-up case whatsoever (e.g., `@testable import Foo.MyEnum; let x = MyEnum.
> asdfasdfasdfNonexistent`).
> What should happen when an unknown case instantiated via a testability
> mechanism is passed to the library that vended the enum (which is able to
> truly exhaustively switch over the enum)?  I would like to see a solution
> to the testability problem and answering this question seems to be the most
> difficult part of finding a solution.  The best answer is not obvious to me.

Indeed, you're quite right. And the whole notion is actually half-baked
because a @testable import should treat the enum as though internal and
therefore exhaustive.

It would appear, however, that testability would require the library itself
to handle unknown cases. That seems annoying but potentially justifiable.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180102/36b62415/attachment.html>

More information about the swift-evolution mailing list