<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 class="">Regardless of syntax, I'm still missing the point on this one.</div><div class=""><br class=""></div><div class="">If there's error-handling and recovery work to be done, isn't this better done without a guard statement, either using `try` to allow the calling chain to respond or using a `do`-`catch` construct. `guard` guarantees scope exit on failure, but so does `try` outside of a`do`-`catch`.</div><div class=""><br class=""></div><div class="">* If you care about just logging errors, you can use a printing form of `try?`. I brought this up on another thread.</div><div class="">* If you care about mitigating a failure, then you should give the `catch` clause the due space and ability to handle recovery that it deserves.</div><div class="">* If you don't care about printing the error, why not use normal `guard` and `try?`.</div><div class=""><br class=""></div><div class="">What is the point of only catching specific errors, or specific types of errors, or etc that deserves a language change here, where it's merged into `guard`?</div><div class=""><br class=""></div><div class="">-- E, dense</div><div class=""><br class=""></div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Mar 8, 2016, at 4:56 PM, Jordan Rose 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="">Another possible syntax:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">guard try let x = foo()</div><div class="">catch let error as FooError {</div><div class="">&nbsp; return nil</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">Downsides:</div><div class="">- You can't limit the 'try' to only part of the expression.</div><div class="">- Actually catching a specific error makes for a very long line, to the point where I automatically wrapped it anyway. Maybe we should just allow one catch.</div><div class="">- It <i class="">still</i>&nbsp;feels like it should be testing for an optional (because of the binding syntax).</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 8, 2016, at 11:37, Jacob Bandes-Storch 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 dir="ltr" class="">Thanks for the feedback, Chris.<div class=""><br class=""></div><div class="">To clarify, are you suggesting that plain variable bindings would support this too (such as "let x = try foo() catch { ... }")? I like this idea. I can also foresee the desire for something like this:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; let x = try foo() catch {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; print(error)</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; x = bar() &nbsp; // by some syntax, provide a fallback value for x, since foo() threw</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; // control flow *can* escape, since x has a value</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">Of course, you can achieve this today with "let x; do { x = try foo() } catch { x = bar() }", or with "let x = try? foo() ?? bar()". I just wonder if it's worth considering the possibility that this new feature would allow control flow to escape in some cases. (After all, control flow can exit the "catch" block we have today.) But it's also nice to be able to glance at the code and see that, unambiguously, control flow can't escape the block.</div><div class=""><br class=""></div><div class="">The reason I originally suggested "guard" is readability: Seeing the word "guard", a reader knows that control flow can't escape the else/catch block. But I understand why guard is still necessary for working with optionals/patterns, and I suppose seeing "try" introducing the expression may be enough.</div><div class=""><br class=""></div><div class="">Do you have thoughts on whether else/catch blocks should be re-orderable?</div><div class=""><br class=""></div><div class="">Another question: should it work with expressions that don't bind variables? Simply "try foo() catch { ... }" ? &nbsp;(At one point I had considered "<b class="">do</b> try ... catch ...", as a braceless analogue of "<b class="">do</b> { try ... } catch ...".)</div><div class="gmail_extra"><br clear="all" class=""><div class=""><div class=""><div dir="ltr" class=""><div class="">Jacob<br class=""></div></div></div></div>
<br class=""><div class="gmail_quote">On Mon, Feb 29, 2016 at 10:34 PM, Chris Lattner <span dir="ltr" class="">&lt;<a href="mailto:clattner@apple.com" target="_blank" class="">clattner@apple.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><span class="">On Feb 29, 2016, at 12:09 PM, Jacob Bandes-Storch via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><div class=""><blockquote type="cite" class=""><b class="">I propose extending guard-statements to handle errors</b> without using the optional "try?" and without a do-block, by allowing the expression to throw, and offering "catch" instead of "else":<br class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">&nbsp; &nbsp; // func foo() throws -&gt; T ...</div><div class="">&nbsp; &nbsp; guard let x = <b class="">try</b> foo <b class="">catch</b> {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; print("the error was: \(<b class="">error</b>)") &nbsp;// the "error" parameter is available here</div>&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control flow to escape this block<div class="">&nbsp; &nbsp; }</div>&nbsp; &nbsp; // control flow cannot reach here if foo() threw an error</div></div></blockquote><br class=""></div></span><div class="">I don’t think that this syntax makes sense, because you’re changing "guard let x = ” to not test an optional.&nbsp; The syntax you’re searching for seems more consistent as a modifier on var/let itself:</div><span class=""><div class=""><br class=""></div><div class="">// func foo() throws -&gt; T ...</div></span><div class="">let x =&nbsp;try&nbsp;foo()&nbsp;catch&nbsp;{<span class=""><br class="">&nbsp; &nbsp; &nbsp; &nbsp; print("the error was: \(error)") &nbsp;// the "error" parameter is available here<br class="">&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control flow to escape this block<br class="">}</span></div><div class=""><br class=""></div><div class="">The guard form of this would still make sense, but the existing “guard let” and “guard case” matching should work as it does.&nbsp; For example, something like this should be allowed:</div><div class=""><br class=""></div><div class=""><div class="">// func bar() throws -&gt; T?</div><div class="">guard let x =&nbsp;try&nbsp;bar() else {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; // this runs if ‘bar’ returns nil.</div><span class="">&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control flow to escape this block</span><span class=""><div class="">} catch&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp; print("the error was: \(error)") &nbsp;// the "error" parameter is available here<br class="">&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control flow to escape this block<br class="">}</div><div class=""><br class=""></div></span><div class="">More generally, the “guard” form would be workable on anything that takes a stmt-condition.&nbsp; This brings “if" and “while” into the mix.</div><span class=""><font color="#888888" class=""><div class=""><br class=""></div><div class="">-Chris</div></font></span></div></div></blockquote></div><br class=""></div></div>
_______________________________________________<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><br class=""></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>