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@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@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution