<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 Dec 21, 2015, at 9:12 PM, Charles Srstka 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=""><div class="">And my two cents is:</div><div class=""><br class=""></div><div class="">NSError is antiquated, and enums conforming to ErrorType, with associated types on the case values, are much better. They are cleaner, they are easier to use, and they are nicer to look at.</div></div></div></blockquote><div><br class=""></div><div>Digressing a bit, I’ve moved away from enums and toward structs for custom ErrorTypes, for several reasons:</div><div><br class=""></div><div>1. Associated values are tuples. This is a big problem in a public API. Any tuple change is a breaking change, and errors thus cannot gain any new diagnostic information with breaking the API:</div><br class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">enum</span> MyError: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">case</span> FileNotFound(url: String)&nbsp;<span style="color: rgb(102, 139, 73);" class="">//</span><span style="color: rgb(102, 139, 73);" class="">&nbsp;1.0</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; ↓</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">enum</span> MyError: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">case</span> FileNotFound(url: String, errno: Int?) <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// Oops! New major release</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div class="">Structs allow for future expansion:</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">struct</span> FileNotFound: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> url: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String &nbsp;// 1.0</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; ↓</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">struct</span> FileNotFound: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> url: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">String</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> errno: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Int</span>?&nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #668b49" class="">// No problem!&nbsp;</span><span style="color: rgb(102, 139, 73);" class="">1.1</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">2. Structs allow error-specific helper methods and derived properties, which can be useful.</div><div class=""><br class=""></div><div class="">3. Structs can implement protocols, which allow shared handling of error cases with shared structure.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Comparing them is nicer:</div><div class=""><br class=""></div><div class="">if case let .FileNotFound(url) = error {</div><div class="">&nbsp; &nbsp; // handle the error</div><div class="">}</div></div></blockquote><div><br class=""></div><div>4. But comparing structs is nicer still, especially when dealing with an optional error. With an enum:</div><div><br class=""></div><div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span>&nbsp;handleFileNotFound(error: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span>?)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> error = error</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">case</span> MyError.FileNotFound(<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> url) = error</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">print</span>(url) }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">But if it’s a struct:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span>&nbsp;handleFileNotFound(error: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span>?)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">if</span> <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">let</span> error = error <span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">as</span>? <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">MyError</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">FileNotFound</span></div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">print</span>(error.<span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">url</span>) }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div></div><div class=""><br class=""></div><div class="">Or if you don’t need the wrapped value:</div></div><div><br class=""></div><div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">func</span> handleFileNotFound(error: <span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">ErrorType</span>?)</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; {</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo; color: rgb(88, 126, 168);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">if</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> error </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">is</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>MyError<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>FileNotFound</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { retry() }</div><div style="margin: 0px; font-size: 10.5px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">So much more readable than the “if let, if case let” dance!</div><div class=""><br class=""></div></div><div>Hmm, I wonder if #1 or #4 suggest any language changes to propose for this list.</div><div><br class=""></div><div>The one big advantage of the error enum is one can use it to enforce handling of all error types in a switch — a need which I have yet to encounter in practice.</div><div><br class=""></div><div>Cheers,</div><div><br class=""></div><div>Paul</div><div><br class=""></div><div><br class=""></div></div></body></html>