<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=""><div><blockquote type="cite" class=""><div class="">On Feb 20, 2017, at 6:04 PM, Chris Lattner &lt;<a href="mailto:clattner@nondot.org" class="">clattner@nondot.org</a>&gt; wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 20, 2017, at 9:57 AM, John McCall 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 style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Feb 19, 2017, at 3:04 PM, Anton Zhilin via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div dir="ltr" class=""><div class="markdown-here-wrapper"><p class="" style="margin: 0px 0px 1.2em !important;">It’s expected that if you need resilience, then you will throw an “open” enum. Essentially, we pass resilience of typed<span class="Apple-converted-space">&nbsp;</span><code class="" 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-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; display: inline;">throws</code><span class="Apple-converted-space">&nbsp;</span>on to those who will hopefully establish resilience of enums.</p><p class="" style="margin: 0px 0px 1.2em !important;">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 class="" style="margin: 0px 0px 1.2em !important;">I don’t like any solution that is based on comments. I think that compiler should always ignore comments.</p></div></div></div></blockquote><div class="">I agree. &nbsp;And in general, this sort of thing is exactly my core concern about adding typed throws to the language: I am completely certain that many programmers will add typed throws annotations because they're programmers and thus, well, probably a little obsessive/compulsive, and they're trying to precisely document the behavior of their function without necessarily thinking about the usefulness of that information for their clients and (if they're writing a library; and really you should almost always be writing code as if you're writing a library) whether they're actually willing to commit to that behavior in their interface. &nbsp;For those programmers, typed throws is just going to box them in and force them into anti-patterns in the long run.</div></div></div></blockquote></div></div></div></div><br class=""><div class="">As you know, I still think that adding typed throws is the right thing to do. &nbsp;I understand your concern about “the feature could be misused” but the same thing is true about many other language features.</div></div></div></blockquote><div><br class=""></div>That's fair, but I do think there's an important difference here. &nbsp;The way I see it, typed-throws is really something of an expert feature, not because it's at all difficult to use, but the reverse: because it's easy to use without really thinking about the consequences. &nbsp;(And the benefits are pretty subtle, too.) &nbsp;I'm not saying that we should design it to be hard to use, but I think maybe it shouldn't immediately suggest itself, and it especially shouldn't come across as just a more specific version of throws.</div><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="">One thing you didn’t mention is that boxing thrown values in an existential requires allocation in the general case. &nbsp;This may be unacceptable for some classes of Swift application (in the embedded / deep systems space) or simply undesirable because of the performance implication.</div></div></div></blockquote><div><br class=""></div></div>So, the performance implication cuts both ways. &nbsp;We can design the ABI for typed-throws so that, say, the callee initializes some buffer that's passed into it. &nbsp;That's an ABI that will kill some potential allocations in deep systems code, no question about it. &nbsp;But in non-deep-systems code, we generally expect that error types will be resilient, which means that there are non-zero dynamic costs for allocating space on the stack for the error. &nbsp;(You can trade code size for performance, but the slow path is a function call to trigger the runtime layout of the type plus a couple of loads.) That space has to be allocated eagerly before the call, so it's paid even in the non-throwing path. &nbsp;And I can't think of anything we could do to shift that cost to the throw-site without either using a fixed-size buffer, requiring a second stack for the thread, or inventing some crazy CC where stack depth can change dynamically across a call.<div class=""><div class=""><div class=""><br class=""></div><div class="">John.</div></div></div></body></html>