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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 2 20:01:47 CST 2018

On Tue, Jan 2, 2018 at 7:02 PM, Goffredo Marocchi <panajev at gmail.com> wrote:

> On 3 Jan 2018, at 00:38, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
> On Tue, Jan 2, 2018 at 4:31 PM, Jonathan Hull <jhull at gbis.com> wrote:
>> I think there are a couple of different definitions running around, and
>> that is confusing things.
>> In my mind, ‘unexpected:’ catches only cases which were unknown at
>> compile time. Adding cases to an enum *should* be a source-breaking change.
>> That is the whole point of this.  We should have to update the switch
>> (either by handling new case explicitly, or by adding default) before
>> successfully compiling.  What ‘unexpected:’ protects against are changes to
>> a linked binary (e.g. iOS) that are now vending cases we didn’t know about
>> when we were compiled.
>> I’ll say it again… framing this idea as one of exhaustiveness is really
>> confusing.  Enums should just always be exhaustive in swift.  There may be
>> cases where we need to use ‘unexpected:’ to handle unexpected/future cases
>> exhaustively.  If we annotate an enum as @frozen, then we won’t need to do
>> that to be exhaustive because we know it won’t change out from under us.
>> Always exhaustive. Much less confusing…
>> Thanks,
>> Jon
> I think, then, you fundamentally disagree with the starting premise of the
> proposal, which is specifically the addition of nonexhaustive enums to the
> language, and making them the default sort of enum so that adding cases *is
> not* a source-breaking change. If your whole purpose is to change the
> proposal so that adding cases will _always_ be a source-breaking change and
> enums are _never_ nonexhaustive, then I'm not sure how to proceed in the
> discussion as we're working towards diametrically opposite goals.
> The main issue is a resilience issue and it mainly affects binary
> frameworks the app links with at runtime and does not package them (read
> mostly Apple ones for the moment)... the fact that enum changes are source
> breaking is the whole entire point of swift’s enum and a best practice
> warning to always have turned on even before with Objective-C. Our goal,
> and yours goal should be the one and the same too IMHO, is not to throw the
> proverbial baby out with the bath water.
> We should look for a solution that allows what Apple and OS framework
> authors need and also what is best for app developers and if we need
> something to do this we pause this proposal until that something is ready
> and merged.
Hmm, I think indeed we disagree fundamentally on what this proposal is
about, or the desired end goal.

If I understand correctly, *your* end goal is simply to enable something
like `@_fixed_layout` for enums, an optimization hint to allow binary
frameworks to add cases without being shipped with apps. You want no
semantic changes to how enums work.

*My* understand of this proposals goal--and I support it--is that it takes
this ABI compatibility problem as a starting point and discovers that there
are fundamentally two semantic categories of enums, ones that are
necessarily exhaustive (there's either something or nothing for an Optional
value, there are three possible comparison results for comparable types,
there are four sides to a rectangular window, etc.) and ones that are not.
It discovers that, empirically, most enums are nonexhaustive, and proposes
changes to the grammar so that Swift distinguishes between these two so as
to prompt developers to deal with the issue of nonexhaustiveness where the
semantics require it. The goal, then, is to introduce new spellings and
semantics to distinguish between two different flavors of enum. Like `open`
vs. `public` for classes, this has implications for ABI compatibility but
isn't just about ABI compatibility.

I was laboring under the idea that we were working to make such a
wide-ranging change as ergonomic as possible, but it seems like you and Jon
do not want such a change at all.

> On Jan 2, 2018, at 1:41 PM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> On Tue, Jan 2, 2018 at 3:27 PM, Kevin Nattinger <swift at nattinger.net>
>> wrote:
>>> [...]
>>> in what other circumstances do we insist that the compiler inform the
>>>> end user about future additions to the API at compile time?
>>>> This isn’t a request for the compiler to inform the user about future
>>>> additions to an API.  It is a request to validate the compiler’s knowledge
>>>> of the *current* state of an API with the *current* state of the
>>>> source code.
>>> Well, it's of course impossible to inform the user about future
>>> additions, so that's poorly phrased on my part. It's about the compiler
>>> informing the end user about *new* additions, part of the *current* state
>>> of the API, that have cropped up since the user last revised the code when
>>> the API was in a *previous* state (or, indistinguishably, members of which
>>> a user is unaware regardless of the temporal sequence of when such members
>>> were added). In what other circumstances do we insist that the compiler
>>> perform this service?
>>> Enums. That's literally how they work today. You are arguing in favor of
>>> actively removing compiler-aided correctness.
>>> There's also protocol requirements
>> No, that's now how enums work today, and it's not how protocol
>> requirements work today. Enums today are all semantically exhaustive; if a
>> case is added in a later version of a library, it's semantically a
>> *different* enum type that happens to share the same name. Not considering
>> all the cases of an exhaustive enum is an _error_, not a _warning_, because
>> there is no basis on which to proceed. This will not change with the
>> proposal. Likewise, adding a protocol requirement without a default
>> implementation is source-breaking. The result is a compiler _error_.
>> The question is, what non-source breaking API additions today cause the
>> compiler to inform the end user of such additions? The answer is: none
>> whatsoever. Not new methods or properties on a type, not even new protocol
>> requirements that have a default implementation.
>> and, arguably, deprecated methods with a proper message ("use foo
>>> instead").
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> 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/75dc1be8/attachment-0001.html>

More information about the swift-evolution mailing list