<div dir="ltr"><div>One of the reasons I like this proposal is at a higher level we are checking for errors and have the ability to exit early if there is an error, I think this aligns well with what `guard` represents, at least to me. Using `try?` effectively ignores the error so if we want convenience we have to give up accuracy of the error handling.</div><div><br></div><div>It also encourages error handling, if we have a function that uses the result of a throwing function it&#39;s very easy to do a `guard` on `try?` and return a generic error instead of putting the function in a do/catch block. With this proposal we can easily put the specific error handing in the catch block.</div><div><br></div><div>The proposal does also changes the concept of guard somewhat, where now it is tied directly to conditionals and `guard/else` is the core concept. The proposal takes out `guard` as the core of and early exit statement the result of it failing it up to how we define our handing of it.</div><div><br></div><div>&gt; The obvious problem is that `guard let` in Swift is closely associated with</div><div>&gt; optional unwrapping. The reader is right to expect a non-optional `result`</div><div>&gt; with `guard let` regardless of the word that comes after conditional</div><div>&gt; expression.</div><div><br></div><div>Yes this does change that idea, but `guard let` is always accompanied by else, additionally because we also use guard along with other conditionals `guard x &gt; 0 else {}` there isn&#39;t a strong tie of guard to optionals. The interfered result type is set by the entire line much like `let a = x &gt; 0 ? &quot;higher&quot; : &quot;lower&quot;`</div><div> </div><div>&gt; The nesting and ceremony, to me, were part of Swift’s philosophy of making error handling explicit.  Merging catch blocks into guards saves you maybe 3-10 lines if you intended to actually handle the error(s), otherwise this effectively try?’s  into a failable pattern match.  At which point, you have to wonder if the error-throwing function you wrote wouldn’t be better off just returning an Optional if you’re going to discard the semantic content of the error.</div><div><br></div><div>I think this proposal goes beyond convenience as we are stating that we want the returned value to be at the same scope as code that uses it. </div><div><br></div><div>If we want to save lines we can do that anyway with something like:</div><div>```</div><div>func divide(x: Int, y: Int) throws -&gt; Int {...}</div><div>let z: Int; do { z = try divide(x: 10, y: 5) } catch {</div><div>    print(error)</div><div>    return</div><div>}</div><div>```</div><div><br></div><div>But we always want `z` to be the result of `divide(x:y:)` having it outside the do/catch looks like we may intend it to be set by something else. With this proposal we are tying `z` to the result of `divide(x:y:)`.</div><div><br></div><div>Another way could be to use a closure</div><div><br></div><div>```</div><div>let z:Int? = {</div><div>    do {</div><div>        return try divide(x: x, y: y)</div><div>    } catch {</div><div>        print(error)</div><div>        return nil</div><div>    }</div><div>}()</div><div>```</div><div>but then we have to use an optional in the case where `divide(x:y:)` does not return one and adding another check for the optional later.</div><div><br></div><div>I think separating guard/else and guard/catch is a great idea because we wouldn&#39;t have the issue of remembering what order else and catch should be in. We can think about guard as guard/[handler]</div><div><br></div><div>The prior thread and in this thread there as been talk of a version without the `guard`. This feels more like an extension of the try keyword, which doesn&#39;t sound to bad to me. It handles the case of keeping the result in the current scope, but it just doesn&#39;t group code in a exit early style.</div></div>