<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="">Hi everyone,</div><div class=""><br class=""></div><div class="">This is a proposal for a very narrow extension to the guard statement. I consider it to be a bug fix, but since it is a language extension, I feel that it should go through the evolution process. Thoughts appreciated!</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div><div class=""><b class=""><br class=""></b></div><div class=""><b class="">Introduction & Motivation<br class=""></b><br class="">The three statements `if`, `while`, and `guard` form a family that all take a rich form of conditions that can include one or more boolean conditions, `#available` clauses, and `let`/`case` pattern bindings. These are described by the `condition-clause` production in the TSPL reference section and as a `stmt-condition` in the compiler source code.</div><div class=""><br class=""></div><div class="">Today, these do not permit trailing closures in any top-level expressions embedded in the condition, because that would be generally ambiguous with the body of an if or while statement:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if foo { // start of trailing closure, or start of the if body?</div><div class=""><br class=""></div><div class="">While it would be possible to tell what is intended in some cases by performing arbitrary lookahead or by performing type checking while parsing, these approaches have significant consequences for the architecture for the compiler. As such, we’ve opted keep the parser simple and disallow this. Unrelated to this proposal, I landed a patch (<a href="https://github.com/apple/swift/commit/30ec0f4128525a16f998e04ae8b1f70180627446" class="">https://github.com/apple/swift/commit/30ec0f4128525a16f998e04ae8b1f70180627446</a>) which *greatly* improves the error messages in some of the most common cases where a developer accidentally tries to do this. </div><div class=""><br class=""></div><div class="">However, while this approach makes sense for `if` and `while` statements, it does not make sense for ‘guard': The body of a guard statement is delineated by the `else` keyword, so there is no ambiguity. A brace is always the start of a trailing closure.</div><div class=""><br class=""></div><div class="">From a historical perspective, the current situation was an oversight. An earlier design for `guard` did not include the `else` keyword (it used the `unless` keyword), and I forgot to fix this when we decided to resyntax it to `guard/else`. </div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">Proposed solution</b><br class=""><br class="">The solution is simple: allow trailing closures in guard bodies. This would allow this silly example to compile correctly:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> f(arr : [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">]?) {</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">guard</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> x = arr?.map {$0+</span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span><span style="font-variant-ligatures: no-common-ligatures" class="">} </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">else</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> preconditionFailure()</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="color: rgb(0, 132, 0);" class="">// ...</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div></blockquote><div class=""><span id="x-apple-selection:end"></span><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><b style="font-family: Helvetica; font-size: 12px;" class="">Detailed Design</b><br style="font-family: Helvetica; font-size: 12px;" class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div>The impact on the compiler is trivial, here’s a patch:</div><div class=""><br class=""></div><div class=""></div></body></html>