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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Dec 19 18:04:56 CST 2017


On Tue, Dec 19, 2017 at 6:31 PM, Kevin Ballard via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On Dec 19, 2017, at 2:58 PM, Ted Kremenek <kremenek at apple.com> wrote:
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0192-non-exhaustive-enums.md
>
>
>    -
>
>    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).
>

I think the proposal represents a very good summary of the pros and cons of
each approach. At the pre-proposal stage, all possible solutions (there are
only three: no default, default to exhaustive, or default to nonexhaustive)
were thoroughly explored, and the proposal as revised here represents a
thoughtful synthesis of the conversation and has a good justification for
the default proposed. I highly doubt that any more back-and-forth on this
will surface new arguments not already covered.


> --
>
> 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.
>

On the contrary, I think that the proposal's behavior for `@testable` is
fully consistent and the best solution possible. It preserves the behavior
that `@testable` imports are treated as though internal, and it allows for
unit tests to have compile-time errors when unexpected cases are added. Any
time you want to test nonexhaustive behavior, you can import without
`@testable`.

--
>
> 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.
>

This, too, I think, has been discussed quite thoroughly, and I think the
proposal synthesizes the discussion and presents the best possible solution.


> 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.
>

This is curious. I wonder if C enums will be nonexhaustive in both Swift 4
and 5 mode, thereby triggering such warnings.

>
>    -
>
>    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 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/20171219/53ec81a4/attachment.html>


More information about the swift-evolution mailing list