[swift-evolution] Handling unknown cases in enums [RE: SE-0192]

Jose Cheyo Jimenez cheyo at masters3d.com
Tue Jan 9 17:07:06 CST 2018


Hi Chris,

This is great. Thanks for spending time on this! I am in favor of `case
#unknown` to only match unknown cases.

1) Would #uknown be available to RawRepresentable structs?

2) How is the #uknown pattern accomplished? Are you suggesting to capture
all the compile time known cases so you can do a diff during
runtime? (Sorry this is not obvious to me)

Previously I suggested having something like `case #known` that would only
match known cases by capturing known cases at compile time ( maybe using a
compile-time variation of
https://github.com/apple/swift-evolution/blob/master/proposals/0194-derived-collection-of-enum-cases.md).
This would give us the equivalent of `case _` == `case #known` + `case
#unknown`.  The only issue I found with `case #known`  is that it would be
the same as `case _` when working with an exhaustive enum.

switch myEnum{
case .X :   //
case .Y :   //
case #unknown : // Matches all runtime unknown cases
case #known : //  Matches all compile known cases
}

On Mon, Jan 8, 2018 at 10:54 PM, Chris Lattner via swift-evolution <
swift-evolution at swift.org> wrote:

> The mega-thread about SE-0192 is a bit large, and I’d like to talk about
> one specific point.  In the review conversation, there has been significant
> objection to the idea of requiring a ‘default’ for switches over enums that
> are non-exhaustive.
>
> This whole discussion is happening because the ABI stability work is
> introducing a new concept to enums - invisible members/inhabitants (and
> making them reasonably prominent).  A closely related feature is that may
> come up in the future is "private cases”.  Private cases are orthogonal to
> API evolution and may even occur on one that is defined to be exhaustive.
>
> Private cases and non-exhaustive enums affect the enum in the same way:
> they say that the enum can have values that a client does not know about.
> Swift requires switches to process *all* of the dynamically possible
> values, which is why the original proposal started out with the simplest
> possible solution: just require ‘default' when processing the cases.
>
>
> *The problems with “unknown case:”*
>
> The popular solution to this probably is currently being pitched as a
> change to the proposal (https://github.com/apple/swift-evolution/pull/777)
> which introduces a new concept “unknown case” as a near-alias for ‘default’:
> https://github.com/jrose-apple/swift-evolution/blob/
> 60d8698d7cde2e1824789b952558bade541415f1/proposals/0192-non-
> exhaustive-enums.md#unknown-case
>
> In short, I think this is the wrong way to solve the problem.  I have
> several concerns with this:
>
> 1) Unlike in C, switch is Swift is a general pattern matching facility -
> not a way of processing integers.  It supports recursive patterns and
> values, and enums are not necessarily at the top-level of the pattern.
> https://github.com/apple/swift/blob/master/docs/PatternMatching.rst is a
> document from early evolution of Swift but contains a good general
> introduction to this.
>
> 2) Swift also has other facilities for pattern matching, including ‘if
> case’.  Making switch inconsistent with them is not great.
>
> 3) As pitched, “unknown case” will match *known* cases too, which is (in
> my opinion :-) oxymoronic.
>
> 4) “unknown case:” changes the basic swift grammar (it isn’t just a
> modifier on case) because case *requires* a pattern.  A better spelling
> would be “unknown default:” which is closer to the semantic provided anyway.
>
> 5) It is entirely reasonable (though rare in practice) to want to handle
> default and unknown cases in the same switch.
>
>
> For all the above reasons, ‘unknown case:' becomes a weird wart put on the
> side of switch/case, not something that fits in naturally with the rest of
> Swift.
>
>
> *Alternative proposal:*
>
> Instead of introducing a new modifier on case/switch, lets just introduce
> a new pattern matching operator that *matches unknown cases*, called
> “#unknown” or “.#unknown” or something (I’m not wed to the syntax, better
> suggestions welcome :).
>
> In the simple case most people are talking about, instead of writing
> “unknown case:” you’d write “case #unknown:” which isn’t much different.
> The nice thing about this is that #unknown slots directly into our pattern
> matching system.  Here is a weird example:
>
> switch someIntEnumTuple {
> case (1, .X):   … matches one combination of int and tuple...
> case (2, .Y):   … matches another combination of int and tuple...
> case (_, #unknown): …  matches any int and any unknown enum case ...
> case default:  … matches anything ...
> }
>
> Furthermore, if you have a switch that enumerates all of the known cases
> and use #unknown, then it falls out of the model that new cases (e.g. due
> to an SDK upgrade or an updated source package) produces the existing build
> error.  As with the original proposal, you can always choose to use
> “default:” instead of “case #unknown:” if you don’t like that behavior.
>
> Of course, if you have an exhaustive enum (e.g. one defined in your own
> module or explicitly marked as such) then #unknown matches nothing, so we
> should warn about it being pointless.
>
>
> This addresses my concerns above:
>
> 1) This fits into patterns in recursive positions, and slots directly into
> the existing grammar for patterns.  It would be a very simple extension to
> the compiler instead of a special case added to switch/case.
>
> 2) Because it slots into the pattern grammar, it works directly with 'if
> case’ and the other pattern matching stuff.
>
> 3) Doesn’t match known cases.
>
> 4) Doesn’t change the case grammar, it just adds a new pattern terminal
> production.
>
> 5) Allows weird cases like the example above.
>
>
> All that said, the #unknown spelling isn’t great, but I’m sure we can find
> something else nice.
>
> Thoughts?
>
> -Chris
>
>
>
> _______________________________________________
> 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/20180109/d2774d30/attachment.html>


More information about the swift-evolution mailing list