<div dir="ltr">On Thu, Jan 12, 2017 at 6:27 PM, Jonathan Hull <span dir="ltr">&lt;<a href="mailto:jhull@gbis.com" target="_blank">jhull@gbis.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">The problem with Java (and ObjC) is that exceptions can propagate unexpectedly into scopes which they weren’t expected and you end up with objects in inconsistent states where it is nearly impossible to continue in any meaningful way.  That can’t happen here as the error will never propagate beyond where it is expected to be.  On the contrary, ‘throws!’ and ‘throws?’ both stop the propagation earlier than ‘throws’.</div></blockquote><div><br></div><div>That&#39;s a fair point about `throws!`.</div><div><br></div><div>It seems that your motivation for `throws!` is to avoid writing `try!` at the call site, since the functionality is otherwise the same. That keyword, notably, is required at most once per statement. So--unless you&#39;re trying to build up a solution for a whole new category of error (as mentioned above)--the question boils down to: does having to write `try!` offer four letters&#39; worth of benefit at the call site? Your answer, if I understand, seems to be: sometimes it might not be worth four letters, and that should be enough to justify a new feature. I think, to make a convincing case, you&#39;ll have to offer real-world use cases where many can agree on that point, sufficient to justify the engineering resources for such a feature. IMO the mere possibility that such a use case may exist is not enough, especially offset against what I would argue is a real benefit to readers of code that every call to a throwing function is currently clearly annotated.</div><div><br></div><div>As to `throws?`, I&#39;m not sure quite sure how it is supposed to work. If a function `throws? -&gt; Int`, is the return value actually of type `Int?`? And if it&#39;s `throws? -&gt; Int?`, then is the return value actually of type `Int??`? In what ways would this design be superior to the already sketched out `Result&lt;T&gt;` type outlined in the Error Handling Rationale document, which several people on this list have lined up to propose? Would a `Result&lt;T&gt;` cover even your use cases for `throws!`?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>Also, ‘try’ is still required to explicitly mark a potential error propagation point, which is what it was designed to do.  You don’t have ‘try’ with the variants because it is by default no longer a propagation point (unless you make it one explicitly with ’try’).</div></div></blockquote><div><br></div><div>If this is quite safe and more convenient, why then shouldn&#39;t it be the behavior for `throws`? (That is, why not just allow people to call throwing functions without `try` and crash if the error isn&#39;t caught? It&#39;d be a purely additive proposal that&#39;s backwards compatible for all currently compiling code.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Thanks,</div><div>Jon</div><div><div class="gmail-h5"><div><div><br><div><blockquote type="cite"><div>On Jan 12, 2017, at 3:50 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="gmail-m_-6323940818606358129Apple-interchange-newline"><div><div dir="ltr"><div>Some additional thoughts: if I recall correctly from my (limited) Java days, throwing in Java worked essentially like your proposed `throws!`. That the Swift model expressly deviates from that example was not by accident, as far as I can tell. According to the error handling docs in the Swift repo:</div><div><br></div><div>&quot;Once an error is thrown, Swift will automatically propagate it out of scopes (that permit it), rather than relying on the programmer to manually check for errors and do their own control flow. This is just a lot less boilerplate for common error handling tasks. However, doing this naively would introduce a lot of implicit control flow, which makes it difficult to reason about the function&#39;s behavior. This is a serious maintenance problem and has traditionally been a considerable source of bugs in languages that heavily use exceptions.</div><div><br></div><div>&quot;Therefore, while Swift automatically propagates errors, it requires that statements and expressions that can implicitly throw be marked with the `try` keyword.&quot;</div><div><br></div><div>So I think what this is saying is that requiring `try` _every time_ is core to the design of Swift error handling, and that `throws!` or even `throws?` would undo it.</div><div><br></div><div><br></div>On Thu, Jan 12, 2017 at 5:35 PM, Xiaodi Wu <span dir="ltr">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span class="gmail-m_-6323940818606358129gmail-">On Thu, Jan 12, 2017 at 4:58 PM, Jonathan Hull via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-m_-6323940818606358129gmail-"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I really like swift’s error handling system overall. It strikes a good balance between safety and usability.<br>
<br>
There are some cases where it would be nice to throw errors, but errors are rarely expected in most use cases, so the overhead of ‘try’, etc… would make things unusable. Thus fatalError or optionals are used instead.  For example, operators like ‘+’ could never throw because adding ’try’ everywhere would make arithmetic unbearable. But in a few cases it would make my algorithm much cleaner if I just assume it will work and then catch overflow/underflow errors if they happen, and resolve each of them with special cases.  Or perhaps I am dealing with user entered values, and want to stop the calculation and display a user visible error (e.g. a symbol in a spreadsheet cell) instead of crashing.<br></blockquote><div><br></div></span><div>Unless I&#39;m mistaken, there is a performance overhead for throwing functions, and thus a much greater barrier to the use cases outlined above is that the performance penalty for &#39;+&#39; would be unacceptable in any case, whatever syntactic sugar you could come up with.</div><span class="gmail-m_-6323940818606358129gmail-"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
I would like to propose adding ‘throws?’ and ‘throws!’ variants to ‘throws’.<br>
<br>
These would be used for cases where error handling is not the default desired behavior, but having it as an option is desired occasionally.</blockquote><div><br></div></span><div>While I admit the idea has an appeal on a practical level, I have an uncomfortable feeling about this. It&#39;s by definition true that error handling is never the default desired behavior, and if I recall correctly the performance of Swift error handling is tuned on the assumption that not throwing is far more common than throwing. If we accept this statement at face value as the justification for including `throws!`, then essentially all `throws` should be `throws!`. And indeed I suspect that if the feature were be implemented, that would rapidly become the case in much written Swift. In essence, then, I think you&#39;re effectively proposing to invert the assignment of responsibility for determining how errors are handled from the call site to the declaration site, at least by default. It goes against an overarching design principle in Swift (discussed earlier in the thread about DefaultConstructible) not to provide such defaults and to require explicitness at the call site.</div><span class="gmail-m_-6323940818606358129gmail-"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Essentially, the user would no longer have to preface the call with ‘try’, as the compiler would implicitly add ‘try?’ or ‘try!’ respectively.<br>
<br>
Thus, the function would act like a non-throwing function (either trapping or returning an optional in the case of error), but the user could add ‘try’ to the call to override that behavior and deal with the error more explicitly.<br>
<br>
Another example would be bounds checking on arrays.  If subscripting arrays was marked as ‘throws!’ then it would have the same default behavior it does now (trapping on bounds error).  But a user could add ‘try?’ to return nil for a bounds error in cases where they explicitly want that, or they could add ‘try’ to deal with it as an error using do-catch.<br></blockquote><div><br></div></span><div>Subscripts cannot throw at all at the moment, and in another thread some of the challenges for designing throwing subscripts were just mentioned. I suspect any sort of throwing subscript will not be possible in the immediate future, so the argument for `throws!` here is moot.</div><span class="gmail-m_-6323940818606358129gmail-"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
I think this would really increase the availability of error handling in areas where it is impractical right now…<br></blockquote><div><br></div></span><div>I think the practical argument could be made stronger by use cases not encumbered by other difficulties as outlined above. Is there a currently throwing function you&#39;ve encountered that would be greatly improved by such a feature? Besides that, though, my discomfort is (as mentioned above) that the practical effect of such a feature is that it will actually altogether invert the default responsibility for error handling, and I&#39;m not sure that it&#39;s entirely consistent with Swift&#39;s design as a consequence. In any case it&#39;d be a far greater change than you&#39;ve made it out to be. Interesting suggestion, definitely.</div><span class="gmail-m_-6323940818606358129gmail-"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Thanks,<br>
Jon<br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
</blockquote></span></div><br></div></div>
</blockquote></div><br></div></div>
</div></blockquote></div><br></div></div></div></div></div></blockquote></div><br></div></div>