<html><head><meta http-equiv="Content-Security-Policy" content="script-src 'self'; img-src * cid: data:;"></head><body style="background-color: rgb(255, 255, 255); background-image: initial; line-height: initial;"><div id="response_container_BBPPID" style="outline:none;font-size:initial;font-family:&quot;Calibri&quot;,&quot;Slate Pro&quot;,sans-serif,&quot;sans-serif&quot;" dir="auto" contenteditable="false"> <div name="BB10" dir="auto" style="width: 100%; padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);">We use enums also when modeling JSON responses from our servers. To allow the server side to add new cases without breaking existing clients, we always add an `undefined` case to our enums.&nbsp;</div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width: 100%; padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);"><br></div><div name="BB10" id="BB10_response_div_BBPPID" dir="auto" style="width: 100%; padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);">Binary frameworks might do the same when exporting enums. When clients compile to a newer version of the framework, new cases will be added and checked by the compiler for exhausiveness. The new version will still contain `undefined` though for the next binary / server-side change.</div>                                                                                                                                      <div name="BB10" dir="auto" style="width: 100%; padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);"> <br style="display:initial"></div>                            <div id="blackberry_signature_BBPPID" name="BB10" dir="auto">     <div name="BB10" dir="auto" style="padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);">Cheers<br>Marc</div> </div></div><div id="_original_msg_header_BBPPID" dir="auto">                                                                                                                                             <table width="100%" style="background-color: white; border-spacing: 0px; display: table; outline: none;" contenteditable="false"><tbody><tr><td colspan="2" style="padding: initial; font-size: initial; text-align: initial; background-color: rgb(255, 255, 255);">                           <div style="border-right: none; border-bottom: none; border-left: none; border-image: initial; border-top: 1pt solid rgb(181, 196, 223); padding: 3pt 0in 0in; font-family: Tahoma, &quot;BB Alpha Sans&quot;, &quot;Slate Pro&quot;; font-size: 10pt;">  <div id="from"><b>Von:</b> swift-evolution@swift.org</div><div id="sent"><b>Gesendet:</b> 2. Januar 2018 6:47 vorm.</div><div id="to"><b>An:</b> matthew@anandabits.com</div><div id="reply_to"><b>Antworten:</b> clattner@nondot.org</div><div id="cc"><b>Cc:</b> swift-evolution@swift.org</div><div id="subject"><b>Betreff:</b> Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums</div></div></td></tr></tbody></table> <br> </div><!--start of _originalContent --><div name="BB10" dir="auto" style="background-image: initial; line-height: initial; outline: none;" contenteditable="false"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Dec 31, 2017, at 12:14 PM, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">I agree that we need a solution to the problem described. &nbsp;I also agree that non-exhaustive is most in keeping with the overall design of Swift at module boundaries. &nbsp;However, I believe this proposal should be modified before being accepted</div></div></div></blockquote><div><br class=""></div><div>Thanks for writing this up - you’ve explained a common concern in an interesting way:</div><div><br class=""></div><blockquote type="cite" class=""><div style="word-wrap:break-word" class=""><div class="">This is likely to be a relatively rare need mostly encountered by 3rd party libraries but it will happen. &nbsp;When it does happen it would be really unfortunate to be forced to use a `default` clause rather than something like a `future` clause which will produce an error when compiled against an SDK where the enum includes cases that are not covered. &nbsp;I can imagine cases where this catch-all case would need to do something <i class="">other than&nbsp;</i>abort the program so I do not like the `switch!` suggestion that has been discussed. &nbsp;The programmer should still be responsible for determining the behavior of unknown cases.</div></div></blockquote><div>..</div><div><blockquote type="cite" class=""><div class="" style="word-wrap:break-word"><div class="">While library authors have a legitimate need to reserve the right to introduce new cases for some enums this need can be met without taking away a useful tool for generating static compiler errors when code does not align with intent (in this case, the intent being to cover all known cases). &nbsp;Switch statements working with these kinds of enums should be required to cover unknown cases but should be able to do so while still being statically checked with regards to known cases. &nbsp;</div></div></blockquote><div class=""><div class="" style="word-wrap:break-word"><div class=""><br class=""></div></div></div></div><div>I think that this could be the crux of some major confusion, the root of which is the difference between source packages and binary packages that are updated outside your control (e.g. the OS, or a dynamic library that is updated independently of your app like a 3rd party plugin). &nbsp;Consider:</div><div><br class=""></div><div>1) When dealing with independently updated binary packages, your code *has* to implement some behavior for unexpected cases if the enum is non-exhaustive. &nbsp;It isn’t acceptable to not handle that case, and it isn’t acceptable to abort because then your app will start crashing when a new OS comes out. You have to build some sort of fallback into your app.</div><div><br class=""></div><div>2) When dealing with a source package that contributes to your app (e.g. through SwiftPM), *YOU* control when you update that package, and therefore it is entirely reasonable to exhaustively handle enums even if that package owner didn’t “intend” for them to be exhaustive. &nbsp;When *you* chose to update the package, you get the “unhandled case” error, and you have maximal “knowability” about the package’s behavior.</div><div><br class=""></div><div><br class=""></div><div>It seems that your concern stems from the fact that the feature as proposed is aligned around module boundaries, and therefore overly punishes source packages like #2. &nbsp;I hope you agree that in case #1, that the feature as proposed is the right and only thing we can do: you really do have to handle unknown future cases somehow.</div><div><br class=""></div><div>If I’m getting this right, then maybe there is a variant of the proposal that ties the error/warning behavior to whether or not a module is a source module vs a binary module. &nbsp;The problem with that right now is that we have no infrastructure in the language to know this…</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><div><br class=""></div><div><br class=""></div></div><br class=""></div><!--end of _originalContent --></div></body></html>