<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 17, 2017, at 5:04 PM, BJ Homer &lt;<a href="mailto:bjhomer@gmail.com" class="">bjhomer@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class="">Please note that, as proposed, enums are always treated as exhaustive *within the same module*. A new user writing MyFirstEnum is likely using it within the same module, and will thus get exhaustive behavior with no extra keywords required.<br class=""></div></div></blockquote><div><br class=""></div><div>• What is your evaluation of the proposal?</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>Uh, +1</div><div><br class=""></div><div>&nbsp;• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>not enough</div><div><br class=""></div><div>Apologies for wasting everyone’s time...</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div><blockquote type="cite" class=""><div dir="auto" class="">-BJ<br class=""><div class=""><br class="">On Sep 17, 2017, at 3:20 PM, Christopher Kornher via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Sep 17, 2017, at 6:33 AM, Rod Brown via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 17 Sep 2017, at 4:35 am, Christopher Kornher &lt;<a href="mailto:ckornher@me.com" class="">ckornher@me.com</a>&gt; wrote:</div><div class=""><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Sep 16, 2017, at 11:28 AM, Christopher Kornher via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><br class=""></div><div class="">If a library writer can’t remember to declare non-exhaustive enums as such, they probably will forget many more important aspects of creating a library. They probably should not be writing libraries. Arguments like this make sense on the surface, but creating libraries involves hundreds or thousands of decisions. I wish you luck in making that process idiot proof. A library linter could easily warn that exposed enums are exhaustive. The exhaustive keyword should be optional to make the decision obvious and suppress warnings. Complicating the user experience in a vain attempt to make “expert" coding safer is misguided.</div></div></div></blockquote></div></div></blockquote><div class=""><br class=""></div><div class="">I think the same logic goes both ways: If a library author can’t remember to declare exhaustive enums as such, they will probably forget many more important aspects of creating a library.</div><div class=""><br class=""></div><div class="">The problem here is fundamental: Exhaustive is a guarantee. A guarantee should require action. Non-Exhaustive guarantees nothing. It makes you safer. That is all.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">1) Exhaustive enums are inherently better: they allow a developer to know that they have covered all possible cases by not using a default.</div><div class="">2) This proposal forces developers to add a keyword to get this behavior in their apps, which is common to all other languages with enums that I have used. This proposal breaks the model common to all (?) current implementations of enums.&nbsp;</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class=""></div><div class="">This may be a little harsh, but there don’t seem to be many advocates for novice and “ordinary” application developers on this list. That is not unexpected given the number of extremely knowledgeable compiler and library developers on this list (for whom I have the highest respect). I believe that there are more creative (and probably more difficult to build) possible solutions to some of the tough problems in Swift’s future. In that spirit, see below.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I personally am an “ordinary” application developer.</div><div class=""><br class=""></div><div class="">I think the issue here is that everyone is seeing Swift as *they* intend to use it. For App Devs, exhaustive switches are nice, which means they really are fighting tooth and nail to keep them. I understand that. But I’m also trying to keep my mind open for “what happens to an app I compiled in iOS 15 that I compiled for iOS 11?” And this gives me pause. I can’t ask Apple or any other library author to be completely knowledgable about every case in the future, and to audit every line of code and manually give non-exhaustive.</div><div class=""><br class=""></div><div class="">Why do people want “exhaustive” to be the default?</div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">Because we like things as they are.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">No, because it makes sense to make common things easy and uncommon things possible.&nbsp;</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">Because we like not having to consider edge cases. Because we want to imagine that will give framework developers the control to make our lives difficult because they’ll just be lazy and make our lives hard by not annotating. And this certainly is a concern. But I think a larger concern is breaking apps left, right and centre, or not being able to extend frameworks because an earlier developer on a project made an oversight.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">This happens all the time: Apple deprecates APIs and asked developers to use new ones. If a library writer does not run (the as-yet hypothetical ) library lint, not participate in thorough code reviews,…, they can simply create a new non-exhaustive enum and deprecate the old one. Yes, there will be some redundant function calls for a while, but again, similar things happen, even in APIs like Apple’s, that (one hopes, at least) are thoroughly reviewed. It is not the end of the world to deprecate and migrate APIs. You &nbsp;may remember garbage collected Objective-C, the change that “viewWillAppear” suddenly was not called when it used to be in iOS. We all survived the elimination of GC and moving our view initialization code. Libraries and developers can survive mistakes and improvements.</div><div class=""><br class=""></div><div class="">ABI stability does not require foolproof, immutable, ABIs. In essence, it is just a guarantee that the build system won’t require rebuilds if library source code stays the same, or is added to, not that applications will never have to be rebuilt in the real world where breaking changes are often required. Adding ABI stability when enums change (in limited ways, don’t forget, removing a case is a breaking change) is a good addition, but it does not rise to the level of requiring degradation of the experience for beginners, IMO.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">Its in everyone’s best interest to think before we put handcuffs on, no matter how painful that is. Even if that means you make apps where you just write “<font face="Menlo" class="" style="font-size: 11px;">default: fatalError(“I don’t handle unreachable defaults”)</font>"</div><div class=""><br class=""></div><div class="">And lets be clear: Swift isn’t an app development language. It also isn’t a framework development language. It’s a multipurpose language designed to Take Over The World™. This means we need to think holistically about what is better for everyone. Not just ourselves.</div></div></div></blockquote><div class=""><br class=""></div><div class="">That includes being easy to learn and understand. Enums are exhaustive in other languages and should be exhaustive by default in Swift. No extra keywords should be required to create “MyFirstEnum” that behaves in a sensible way. The documentation that describes why you need to write a ‘default’ clause or 'exhaustive' when you have all the possible cases written down should be interesting. May I suggest: “You see, if you write a library (don’t worry about what that means right now) you don’t have to worry about being not very good at it. If and when you write one, it will be a tiny bit easier, so write this meaningless clause or the magical keyword — your choice.”&nbsp;</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><br class=""></div><div class="">If you declare it is exhaustive and it was an oversight, and then realise after the fact that you are wrong, you have to open it up. This will break third party apps. It will be disallowed by the ABI compatibility requirements.</div><div class=""><br class=""></div><div class="">If you declare it isn’t exhaustive due to an oversight (or perhaps you’re just not sure yet), and then realise after the fact it is exhaustive, you can close it up. This will not break third party apps. It will also be allowed for ABI compatibility.</div><div class=""><br class=""></div><div class="">This benefits everyone. Make library owners choose a guarantee, rather than be defaulted into it. Much like they have to declare choose to declare “final” on a class: you can’t retroactively reneg that promise: it will break everyone who assumed it to be the case!</div></div></div></blockquote><div class=""><br class=""></div><div class="">It does not benefit the creation of 90+% of enums. It is one more arcane rule for the vast majority of developers.</div></div></div></blockquote><div class=""><br class=""></div><div class="">The Swift compiler could offer a “strict enum exhaustiveness” (bikeshedding not included) switch that could be enabled by default for library targets and disabled by default for “application” targets. The switch would make not explicitly specifying exhaustiveness an error or warning when enabled. Perhaps this could be combined with other options that would tailor the development experience for library/application developers. This would help avoid “zero-sum” choices between benefitting library or application developers in the future.</div></div></div></blockquote><div class=""><br class=""></div><div class="">The Swift team have fundamentally opposed such pushes for “compiler modes” for a long time. I don’t expect they will embrace them now, nor do I think they should just to avoid us devs having to write the occasional “default” clause. This is, to be clear, a relatively rare case.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">It is probably a good choice, but there are potential upsides. Oh, course, this could easily lead to a library dialect and an application dialect of Swift. That is already the de-facto state of affairs for many languages, including Swift. Would formalizing the difference make of “taking over the world” more attainable or just create a mess? &nbsp;A "library switch" could be horribly abused, and should only be used as a last resort. Ideally, it would only generate warnings in library mode.&nbsp;</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class=""></div><div class="">Xcode and the SPM should be able to distinguish between the target types and generate the proper defaults. I do not believe that this is too mysterious for developers. There would be learning step for developers wiring their first library, but that is not necessarily a bad thing since creating a reusable library requires a different mindset than creating an application.</div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div><div class="">Exhaustive and open by default with keywords to close things down if the framework author wants them.</div><div class=""><br class=""><div class="">Sent from my iPhone</div><div class=""><br class="">On 16 Sep 2017, at 09:55, David Hart via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class="">I’m still very much bothered by having 2 new keywords. I would really prefer the following plan:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">Exhaustive by default in Swift 4</li><li class="">No new keyword in Swift 4 to change that behaviour</li><li class="">Non-exhaustive by default outside the module in Swift 5</li><li class=""><b class="">exhaustive</b><span class="Apple-converted-space">&nbsp;</span>keyword to change the default behaviour</li></ul><div class=""><br class=""></div></div><div class="">Like that, we don’t need<span class="Apple-converted-space">&nbsp;</span><b class="">nonexhaustive</b>.</div><div class=""><br class=""></div><div class="">Thoughts?</div><div class="">David.</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 13 Sep 2017, at 21:16, Jordan Rose via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">Proposal updated, same URL:&nbsp;<a href="https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md" class="">https://github.com/jrose-apple/swift-evolution/blob/non-exhaustive-enums/proposals/nnnn-non-exhaustive-enums.md</a>.</div><div class=""><br class=""></div><div class="">Thanks again for all the feedback so far, everyone!</div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Sep 12, 2017, at 17:55, Jordan Rose via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Sorry, I got distracted by other tasks! Both the discussion here and within Apple has moved towards making "non-exhaustive" the default, which, to be honest, I too think is the best design. I'll update the proposal today to reflect that, though I still want to keep both the "nonexhaustive" and "exhaustive" keywords for Swift 4 compatibility for now (or whatever we end up naming them). The compatibility design is a little less ambitious than Brent's; as currently proposed, Swift 4 mode continues to default to 'exhaustive' all the time, even in the actual Swift 5 release.<br class=""><br class="">I still want to respond to Brent's points directly, but I think you and Vladimir have done a good job discussing them already. I'll send out the updated proposal tomorrow, after I have a little more time to think about #invalid.<br class=""><br class="">Thanks for putting time into this!<br class="">Jordan<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Sep 9, 2017, at 17:34, Rod Brown &lt;<a href="mailto:rodney.brown6@icloud.com" class="">rodney.brown6@icloud.com</a>&gt; wrote:<br class=""><br class="">Jordan,<br class=""><br class="">Do you have any other thoughts about the ongoing discussion here, especially regarding Chris’ comments? As you’re the one pushing this forward, I’d really like to know what your thoughts are regarding this?<br class=""><br class="">- Rod<br class=""></blockquote><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">_______________________________________________</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;">swift-evolution mailing list</span><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="mailto:swift-evolution@swift.org" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">swift-evolution@swift.org</a><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></blockquote></div><br class=""></body></html>