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

Chris Lattner clattner at nondot.org
Wed Jan 10 00:08:13 CST 2018

On Jan 9, 2018, at 12:27 PM, Vladimir.S <svabox at gmail.com> wrote:
>> 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.
> Are you saying here about situation, when new case is added in non-frozen enum, but we are compiling the old code with absent new case but with "unknown case" in switch? As stated in proposal, in this case we'll have a warning exactly for source compatibility reason: "..unknown case matches any value. ... the compiler will produce a warning if all known elements of the enum have not already been matched. This is a warning rather than an error so that adding new elements to the enum remains a source-compatible change." Do you suggest to change that warning into error?
> Or you are saying about another situation when “unknown case” will match known cases too in the initial proposal ?

In the proposal, ‘unknown case’ is a synonym for default with changes to warning generation.  This means that it matches everything, including cases known at static compile time.

>> 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.
> Are you suggesting to have this?:
> switch val {
> case .one: ...
> case .two: ...
> case #unknown: ...
> default: ..
> }


> So, all new cases, introduced in external module after compilation of that code will fall into "case #unknown: ..." bucket, but all "known"(at the moment of compilation) cases but not .one/.two - into "default:..." ? Personally I like that, so if I need this - I will be able to express this, but that rule seems like complicated to understand.
> But this can be really helpful in situation, when you *at compilation time" thinks that you are not interested in anything but .one/.two cases of that enum, but in case of new values - you want to show(for example) a warning for app user.

Exactly.  It is a narrow case, but it is important to me that we provide primitives that compose properly.

> Do I understand correctly, that you suggest the same behavior as in original(updated) proposal:
> * if we have a switch on non-frozen enum value, and enumerated some cases, and have "case #unknown" - we'll have a warning(error?) if (at the moment of compilation) not all known enums are processed in "switch” ?


> Just to be sure.
> Btw, should this be valid? :
> switch val {
>  case #unknown:... // I'm only interested if new values were added to that external enum
>  default: ... // as I understand, "default" will be required here
> }

Yes, this would be very weird to write, but would be valid: the default matches all known cases at compile time.  I’d suggest that you write that as a “if case #unknown” with an else though.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180109/ee81ae8c/attachment.html>

More information about the swift-evolution mailing list