<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">Hi Slava,</div><div class=""><br class=""></div>I think we may be referring to different things. For whatever it’s worth, I agree with your reasoning on all the points you brought up. I also <i class="">don’t </i>think having a 'default: fatalError()’ case is a good idea because then a library change can cause crashes in a running version of an application.<div class=""><br class=""></div><div class="">What I mean by some sort of ‘complete switch’ statement is that it would be compiled as per a normal ‘switch’ but error <i class="">at compile time </i>if it’s not complete against the known set of cases as compile time. Assuming an enum with known cases [a, b] at compile time,</div><div class=""><br class=""></div><div class="">switch nonExhaustiveEnum {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case a:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print(“a”)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case b:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print(“b”)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>default:</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>break</div><div class="">}</div><div class=""><br class=""></div><div class="">would be exactly equivalent to:</div><div class=""><br class=""></div><div class=""><div class="">complete switch nonExhaustiveEnum {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>case a:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>print(“a”)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>case b:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>print(“b”)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>unknown: // the ‘unknown’ case would only be required for non-exhaustive enums</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>break</div><div class="">}</div><div class=""><br class=""></div><div class="">where the keywords ‘complete’ and ‘unknown’ are up for debate. If, however, the programmer wrote:</div><div class=""><br class=""></div><div class=""><div class="">complete switch nonExhaustiveEnum {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>case a:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>print(“a”)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>unknown:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>break</div><div class="">}</div></div><div class=""><br class=""></div><div class="">the compiler would give an error that there are unhandled cases in the switch statement, whereas</div><div class=""><br class=""></div><div class=""><div class="">switch nonExhaustiveEnum {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>case a:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>print(“a”)</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>default:</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>break</div><div class="">}</div></div><div class=""><br class=""></div><div class="">would compile without issue. If a user didn’t know about the existence of the ‘complete switch’ construct, they could just use normal ‘switch’ statements and miss out on the completeness checking.</div><div class=""><br class=""></div><div class="">Thomas</div><div><br class=""><blockquote type="cite" class=""><div class="">On 24/12/2017, at 1:15 PM, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> 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; line-break: after-white-space;" class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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=""><div class=""><span class=""></span></div><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></span></font></div><blockquote type="cite" class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class="">What are your thoughts on `final switch` as a way to treat any enum as exhaustible?</span></font><div class=""><a href="https://dlang.org/spec/statement.html#FinalSwitchStatement" style="background-color: rgba(255, 255, 255, 0);" class=""><font class="">https://dlang.org/spec/statement.html#FinalSwitchStatement</font></a></div></blockquote><blockquote type="cite" class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" 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></span></font></blockquote></div><span style="background-color: rgba(255, 255, 255, 0);" class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div>I’d be very much in favour of this (qualms about the naming of the ‘final’ keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). </span><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Looking back at the proposal, I noticed that something similar was mentioned that I earlier missed. In the proposal, it says:</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><blockquote type="cite" preoffsettop="179" class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">However, this results in some of your code being <em style="box-sizing: border-box;" class="">impossible to test,</em> since you can't write a test that passes an unknown value to this switch.<br class=""></span></font></blockquote><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><span style="background-color: rgba(255, 255, 255, 0);" class="">Is that strictly true? Would it be theoretically possible for the compiler to emit or make accessible a special ‘test’ case for non-exhaustive enums that can only be used in test modules or e.g. by a ‘EnumName(testCaseNamed:)’, constructor? There <i class="">is</i> potential for abuse there but it <i class="">would </i>address that particular issue. </span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Regardless, I still feel something like a ‘final switch’ is necessary if this proposal is introduced, and that it fits with the ‘progressive disclosure’ notion; once you learn this keyword you have a means to check for completeness, but people unaware of it could just use a ‘default’ case as per usual and not be concerned with exhaustiveness checking. </span></div></div></div></div></blockquote><br class=""></div><div class="">My general philosophy with syntax sugar is that it should do more than just remove a constant number of tokens. Basically you’re saying that</div><div class=""><br class=""></div><div class="">final switch x {}</div><div class=""><br class=""></div><div class="">just expands to</div><div class=""><br class=""></div><div class="">swift x {</div><div class="">default: fatalError()</div><div class="">}</div><div class=""><br class=""></div><div class="">I don’t think a language construct like this carries its weight.</div><div class=""><br class=""></div><div class="">For example, generics have a multiplicative effect on code size — they prevent you from having to write an arbitrary number of versions of the same algorithm for different concrete types.</div><div class=""><br class=""></div><div class="">Another example is optionals — while optionals don’t necessarily make code shorter, they make it more understandable, and having optionals in the language rules out entire classes of errors at compile time.</div><div class=""><br class=""></div><div class="">On the other hand, a language feature that just reduces the number of tokens without any second-order effects makes code harder to read, the language harder to learn, and the compiler buggier and harder to maintain without much benefit. So I think for the long term health of the language we should avoid ‘shortcuts’ like this.</div><div class=""><br class=""></div><div class="">Slava</div></div></div></blockquote></div><br class=""></div></body></html>