<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 19 Feb 2017, at 21:04, Anton Zhilin &lt;<a href="mailto:antonyzhilin@gmail.com" class="">antonyzhilin@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="markdown-here-wrapper" style=""><p style="margin:0px 0px 1.2em!important" class="">It’s expected that if you need resilience, then you will throw an “open” enum. Essentially, we pass resilience of typed <code style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);background-color:rgb(248,248,248);border-radius:3px;display:inline" class="">throws</code> on to those who will hopefully establish resilience of enums.</p><p style="margin:0px 0px 1.2em!important" class="">If you prefer separate error types, then declare a base protocol for all your error types and throw a protocol existential. You won’t even need default case in switches, if closed protocols make it into the language.</p><p style="margin:0px 0px 1.2em!important" class="">I don’t like any solution that is based on comments. I think that compiler should always ignore comments.</p><div class=""><br class=""></div></div></div></div></blockquote><br class=""></div><div>Open enums can only add cases, not remove them. That means that new versions of a function will similarly only be able to add errors, and won’t be able to communicate that certain errors are no longer thrown. Protocols aren’t a solution, because you will need to write verbose conformances for all of your Error types.</div><div><br class=""></div><div>Let me put this in another (perhaps more palatable) way. Forget comments, let’s say its part of some hidden metadata:</div><div><br class=""></div><div>- The compiler lists every error which can be thrown by a function (it’s easily able to do that)</div><div>- Rather than making this part of the signature, the signature only says “throws an Error” and the actual Error list is written somewhere in the module as documentation/metadata.</div><div><br class=""></div><div>Here’s why it’s so good:</div><div><br class=""></div><div>- It’s completely free (you don’t write anything). The compiler generates everything for you.</div><div>- It’s **completely optional**: it won’t make your structure your Errors in a way that's less usable in a type-system sense for clients who don’t care about exhaustive catching.</div><div>- Exhaustive catching within your own module for free (you can omit a catch-all, the compiler won’t complain)</div><div><br class=""></div><div>It’s good for resiliency, too:</div><div><br class=""></div><div>- Non-resilient functions always reserve the right to throw new Errors in later versions. No system will get exhaustive catching for them anyway.</div><div>- If you stop throwing a specific Error, nothing breaks - it simply vanishes from the documentation/metadata. The compiler can simply warn about the redundant catch.</div><div>- Resilient (@versioned) functions can still offer exhaustive catching if we want to offer that. We might decide to make that opt-in/opt-out, because it would mean they would be limited to removing Errors, and never adding new ones.</div><div>—&gt; As with any ABI promise, we will trap or it will be UB if you break the contract. We couldn’t validate it when compiling, but theoretically a validator could be built which compared two library versions.</div><div><br class=""></div><div>- Karl</div><div><br class=""></div></body></html>