<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div id="bloop_customfont" style="color: rgb(0, 0, 0); margin: 0px;"><font face="SourceCodePro-Regular">This is the exact same topic I started over a moth ago:&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160201/009296.html">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160201/009296.html</a></font></div><div id="bloop_customfont" style="color: rgb(0, 0, 0); margin: 0px;"><font face="SourceCodePro-Regular"><br></font></div><div id="bloop_customfont" style="color: rgb(0, 0, 0); margin: 0px;"><font face="SourceCodePro-Regular">As already discussed in my topic it’s better not to use `guard` in this case, but add a new single statement `try catch` mechanism.</font></div><div id="bloop_customfont" style="color: rgb(0, 0, 0); margin: 0px;"><font face="SourceCodePro-Regular"><br></font></div><div id="bloop_customfont" style="margin: 0px;"><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">func scope() {        </font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space:pre">        </span>let foo: Int? = try throwingFuncReturns() catch {&nbsp;</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">                // foo can’t be available here, because its</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">                </span>// declared on the same line </font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">                // by default you can fall through the catch block</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space:pre">        </span>// using foo would not be save here</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        guard let unwrappedFoo = foo else {&nbsp;</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">                return</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        use(unwrappedFoo)</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">}</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">On way to solve this problem for throwing functions that return a value could look like this:</font></pre><pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">func scope() {        </font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>let foo: Int?&nbsp;</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space:pre">        </span>foo = try throwingFuncReturns() catch {&nbsp;</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">                // foo is available here</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">                </span>// make sure to initialize foo here if you do not return from here</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>//&nbsp;foo is save here</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        guard let unwrappedFoo = foo else {&nbsp;</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">                return</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">        use(unwrappedFoo)</font></pre><pre style="color: rgb(0, 0, 0); white-space: pre-wrap;"><font face="SourceCodePro-Regular">}</font></pre><pre><span style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">And because we just can’t use a single `try catch` statement like we would wish, we can bring back the `do` keyword.</font></span></pre><pre><pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">func scope() {        </font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>let foo: Int?&nbsp;</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>do foo = try throwingFuncReturns() catch {&nbsp;</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space:pre">                </span>// init foo (+ more optional work) or return</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">        guard let unwrappedFoo = foo else {&nbsp;</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">                return</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">        use(unwrappedFoo)</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">}</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">This is the best solution I could come up with, and it does work fine with functions that do not return a value:</font></pre><pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">func scope() {        </font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>let foo: Int?&nbsp;</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular"><span class="Apple-tab-span" style="white-space: pre;">        </span>do try catchMeIfYouCan() catch {&nbsp;</font></pre><pre><font face="SourceCodePro-Regular"><span style="white-space: pre-wrap;">                // do some work -&gt; fallthough or return</span></font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">        }</font></pre><pre style="white-space: pre-wrap;"><font face="SourceCodePro-Regular">}</font></pre><pre><font face="SourceCodePro-Regular"><span style="white-space: pre-wrap;">But from my personal point of view I would remove the `do` keyword in single `try catch` statements. The `do` keyboard is only needed for the `do body` if there are more lines of code to process before catching an error.</span></font></pre><pre><font face="SourceCodePro-Regular"><span style="white-space: pre-wrap;">A single `do catch` mechanism would be good for escaping another pyramid of doom like we had with `if` before the `guard` mechanism was introduced.</span></font></pre></pre></pre></pre></pre></div> <div id="bloop_sign_1457873829947699968" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev</div></div> <br><p class="airmail_on">Am 8. März 2016 bei 20:37:52, Jacob Bandes-Storch via swift-evolution (<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div><div></div><div>


<title></title>


<div dir="ltr">Thanks for the feedback, Chris.
<div><br></div>
<div>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><br></div>
<div>&nbsp; &nbsp; let x = try foo() catch {</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; print(error)</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; x = bar() &nbsp; // by some
syntax, provide a fallback value for x, since foo() threw</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; // control flow *can* escape,
since x has a value</div>
<div>&nbsp; &nbsp; }</div>
<div><br></div>
<div>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><br></div>
<div>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><br></div>
<div>Do you have thoughts on whether else/catch blocks should be
re-orderable?</div>
<div><br></div>
<div>Another question: should it work with expressions that don't
bind variables? Simply "try foo() catch { ... }" ? &nbsp;(At one
point I had considered "<b>do</b> try ... catch ...", as a
braceless analogue of "<b>do</b> { try ... } catch ...".)</div>
<div class="gmail_extra"><br clear="all">
<div>
<div>
<div dir="ltr">
<div>Jacob<br></div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">On Mon, Feb 29, 2016 at 10:34 PM, Chris
Lattner <span dir="ltr">&lt;<a href="mailto:clattner@apple.com" target="_blank">clattner@apple.com</a>&gt;</span> wrote:<br>
<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"><span>On Feb 29, 2016, at 12:09
PM, Jacob Bandes-Storch via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></span>
<div>
<blockquote type="cite"><span><b>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></span>
<div>
<div dir="ltr">
<div><span><br></span></div>
<div><span>&nbsp; &nbsp; // func foo() throws -&gt; T
...</span></div>
<div><span>&nbsp; &nbsp; guard let x = <b>try</b> foo <b>catch</b>
{</span></div>
<div><span>&nbsp; &nbsp; &nbsp; &nbsp; print("the error was:
\(<b>error</b>)") &nbsp;// the "error" parameter is available
here</span></div>
<span>&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow
control flow to escape this block</span>
<div><span>&nbsp; &nbsp; }</span></div>
<span>&nbsp; &nbsp; // control flow cannot reach here if foo()
threw an error</span></div>
</div>
</blockquote>
<span><br></span></div>
<div>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>
<div><span><br></span></div>
<div><span>// func foo() throws -&gt; T ...</span></div>
<div>let x =&nbsp;try&nbsp;foo()&nbsp;catch&nbsp;{<span><br>
&nbsp; &nbsp; &nbsp; &nbsp; print("the error was: \(error)")
&nbsp;// the "error" parameter is available here<br>
&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control
flow to escape this block<br>
}</span></div>
<div><br></div>
<div>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><br></div>
<div>
<div>// func bar() throws -&gt; T?</div>
<div>guard let x =&nbsp;try&nbsp;bar() else {</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; // this runs if ‘bar’ returns
nil.</div>
<span>&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow
control flow to escape this block</span>
<div><span>} catch&nbsp;{<br>
&nbsp; &nbsp; &nbsp; &nbsp; print("the error was: \(error)")
&nbsp;// the "error" parameter is available here<br>
&nbsp; &nbsp; &nbsp; &nbsp; // the compiler does not allow control
flow to escape this block<br>
}</span></div>
<div><span><br></span></div>
<div>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>
<div><span><font color="#888888"><br></font></span></div>
<div><span><font color="#888888">-Chris</font></span></div>
</div>
</div>
</blockquote>
</div>
<br></div>
</div>


_______________________________________________<br>swift-evolution mailing list<br>swift-evolution@swift.org<br>https://lists.swift.org/mailman/listinfo/swift-evolution<br></div></div></span></blockquote></body></html>