I am not convinced by these arguments, they seem to be a ‘poor man’s’ versioning system. For example consider:
// In module. public enum E { case A, B, C } // In application. switch e { case A: a() default: d() unknown case: u() } When e == B or C is u() or d() called? I would expect d() since the application programmer obviously intends to handle unexpected differently than default. Now when E is modified and case D added by the module programmer I would expect B and C to still call d() and D to call u(). To achieve the above behaviour the switch encodes that when it compiled default was for B and C and therefore D is the new case and therefore it calls u(). When the code is recompiled against the new module the behaviour changes. D will now call d(). This will be without a warning. Hence I am classing this as a ‘poor man’s’ module system. Possible solutions include: 1. You can’t have a default with an extensible enum, but you must have a unknown case. This prevents handling default cases at all, you have to list all the existing cases separately. 2. As described above in 1 the unknown case does very little. Instead just use default and don’t introduce unknown. 3. Have a versioned module system that requires enum cases and matching switch statements to be versioned. EG: // In module. @version(1) public enum E { case A, B, C } @version(1.6) public enum E { case A, C, D } // In application. @version(1.5) switch e { case A: a() default: d() unknown case: u() } The module system would have to publish which enum cases were available for each version including all old versions. Note how the above notation allows removal and addition of cases. -- Howard. > On 3 Jan 2018, at 12:26 am, Kelvin Ma via swift-evolution > <swift-evolution@swift.org> wrote: > > > >> On Tue, Jan 2, 2018 at 11:45 PM, Nevin Brackett-Rozinsky via swift-evolution >> <swift-evolution@swift.org> wrote: >>> On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> [Proposal: >>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md] >>> >>> Whew! Thanks for your feedback, everyone. On the lighter side of >>> feedback—naming things—it seems that most people seem to like '@frozen', >>> and that does in fact have the connotations we want it to have. I like it >>> too. >>> >>> More seriously, this discussion has convinced me that it's worth including >>> what the proposal discusses as a 'future' case. The key point that swayed >>> me is that this can produce a warning when the switch is missing a case >>> rather than an error, which both provides the necessary compiler feedback >>> to update your code and allows your dependencies to continue compiling when >>> you update to a newer SDK. I know people on both sides won't be 100% >>> satisfied with this, but does it seem like a reasonable compromise? >>> >>> The next question is how to spell it. I'm leaning towards `unexpected >>> case:`, which (a) is backwards-compatible, and (b) also handles "private >>> cases", either the fake kind that you can do in C (as described in the >>> proposal), or some real feature we might add to Swift some day. `unknown >>> case:` isn't bad either. >>> >>> I too would like to just do `unknown:` or `unexpected:` but that's >>> technically a source-breaking change: >>> >>> switch foo { >>> case bar: >>> unknown: >>> while baz() { >>> while garply() { >>> if quux() { >>> break unknown >>> } >>> } >>> } >>> } >>> >>> Another downside of the `unexpected case:` spelling is that it doesn't work >>> as part of a larger pattern. I don't have a good answer for that one, but >>> perhaps it's acceptable for now. >>> >>> I'll write up a revision of the proposal soon and make sure the core team >>> gets my recommendation when they discuss the results of the review. >>> >>> --- >>> >>> I'll respond to a few of the more intricate discussions tomorrow, including >>> the syntax of putting a new declaration inside the enum rather than >>> outside. Thank you again, everyone, and happy new year! >>> >>> Jordan >> >> >> +1 to warning instead of error >> +1 to unknown/unexpected case >> +1 to “@frozen” or any other reasonable spelling, they are all fine by me. > > +1 to “@tangled” because abi is complicated > >> >> The one remaining problem to solve is making sure multi-module apps can >> leave out the unknown/unexpected case on enums from modules which are part >> of the app itself and thus cannot be updated independently of it. John >> McCall’s version-locking plan sounds promising, though we should explore the >> available options before finalizing a course. >> >> Perhaps we need a concept of submodules, or supermodules, or some other way >> to demarcate the boundaries of a resilience domain. >> >> Nevin > > i would support a proper submodule system over some verson-locking system > that only the most advanced users will probably know about. i think modules > should be one level higher than what they’re currently being used for right > now for lack of a better alternative (one application should never have to > define more than one capital M Module). submodules shouldn’t be that hard to > implement, though the submodule names should be part of ABI to avoid name > mangling problems > > _______________________________________________ > 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