<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">I am not convinced by these arguments, they seem to be a ‘poor man’s’ versioning system. For example consider:<div><br></div><div> // In module. </div><div> public enum E {</div><div> case A, B, C</div><div> }</div><div><br></div><div> // In application. </div><div> switch e {</div><div> case A: a()</div><div> default: d()</div><div> <span style="background-color: rgba(255, 255, 255, 0);">unknown case: u()</span></div><div> }</div><div><br></div><div>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. </div><div><br></div><div>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(). </div><div><br></div><div>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(). </div><div><br></div><div>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. </div><div><br></div><div>Possible solutions include:</div><div><br></div><div> 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. </div><div><br></div><div> 2. As described above in 1 the unknown case does very little. Instead just use default and don’t introduce unknown. </div><div><br></div><div> 3. Have a versioned module system that requires enum cases and matching switch statements to be versioned. EG:</div><div><br></div><div><div><span style="background-color: rgba(255, 255, 255, 0);"> // In module. </span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> @version(1) public enum E {</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> case A, B, C</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div><div><span style="background-color: rgba(255, 255, 255, 0);"> @version(1.6) public enum E {</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> case A, C, D</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> // In application. </span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> @version(1.5) switch e {</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> case A: a()</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> default: d()</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> unknown case: u()</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"> }</span></div><div><br></div></div><div>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. </div><div><br><div id="AppleMailSignature">-- Howard. </div><div><br>On 3 Jan 2018, at 12:26 am, Kelvin Ma via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 2, 2018 at 11:45 PM, Nevin Brackett-Rozinsky via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Tue, Jan 2, 2018 at 9:07 PM, Jordan Rose via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>[Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md" style="font-family:Helvetica,arial,sans-serif" target="_blank">https://github.com/<wbr>apple/swift-evolution/blob/mas<wbr>ter/proposals/0192-non-exhaust<wbr>ive-enums.md</a>]</div><div><br></div><div>Whew! Thanks for your feedback, everyone. On the lighter side of feedback—naming things—it seems that most people seem to like '<b>@frozen</b>', and that does in fact have the connotations we want it to have. I like it too.</div><div><br></div><div>More seriously, this discussion has convinced me that it's worth including what the proposal discusses as a <b>'future' case</b>. The key point that swayed me is that this can produce a <i>warning</i> when the switch is missing a case rather than an <i>error,</i> 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?</div><div><br></div><div>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.</div><div><br></div><div>I too would like to just do `unknown:` or `unexpected:` but that's technically a source-breaking change:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>switch foo {</div><div>case bar:</div><div> unknown:</div><div> while baz() {</div><div> while garply() {</div><div> if quux() {</div><div> break unknown</div><div> }</div><div> }</div><div> }</div><div>}</div></blockquote><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>---</div><div><br></div><div><div>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!</div></div><div><br></div><div>Jordan</div></div></blockquote><div><br></div><div><br></div></div></div><div>+1 to warning instead of error<br></div><div>+1 to unknown/unexpected case</div><div>+1 to “@frozen” or any other reasonable spelling, they are all fine by me.</div></div></div></div></blockquote><div><br></div><div>+1 to “@tangled” because abi is complicated<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>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.</div><div><br></div><div>Perhaps we need a concept of submodules, or supermodules, or some other way to demarcate the boundaries of a resilience domain.</div><div><br></div><div>Nevin</div></div></div></div></blockquote><div><br></div><div>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<br></div></div><br></div></div>
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></body></html>