+1, it’s a straightforward improvement. It’s a good thing for the language not 
to surprise me rejecting something that seems completely reasonable.

— Radek

> On 23 Mar 2016, at 07:03, Chris Lattner via swift-evolution 
> <[email protected]> wrote:
> 
> Hi everyone,
> 
> 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!
> 
> -Chris
> 
> 
> Introduction & Motivation
> 
> 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.
> 
> 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:
> 
>       if foo {   // start of trailing closure, or start of the if body?
> 
> 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 
> (https://github.com/apple/swift/commit/30ec0f4128525a16f998e04ae8b1f70180627446
>  
> <https://github.com/apple/swift/commit/30ec0f4128525a16f998e04ae8b1f70180627446>)
>  which *greatly* improves the error messages in some of the most common cases 
> where a developer accidentally tries to do this. 
> 
> 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.
> 
> 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`. 
> 
> 
> Proposed solution
> 
> The solution is simple: allow trailing closures in guard bodies.  This would 
> allow this silly example to compile correctly:
> 
> func f(arr : [Int]?) {
>   guard let x = arr?.map {$0+1} else {
>     preconditionFailure()
>   }
> 
>   // ...
> }
> 
> Detailed Design
> 
> The impact on the compiler is trivial, here’s a patch:
> 
> <guard.patch>
> 
> 
> 
> Impact on existing code
> 
> There is no impact on existing code.  This only makes formerly invalid code 
> start being accepted.
> 
> 
> Alternatives considered
> 
> There are three primary alternatives: do nothing, expand the scope of ‘if' 
> and ‘while’ conditions as well, and significantly change the syntax of guard.
> 
> Do nothing: It can be argued that this change would make guard inconsistent 
> with the restrictions of ‘if’ and ‘while’ and that inconsistency would be 
> confusing.  On the other hand, I am arguing that this is an arbitrary 
> restriction.
> 
> Expand the scope of “if” and “while” statements:  Through enough heroics and 
> lookahead we could consider relaxing the trailing closure requirements on 
> `if` and `while` statements as well.  While this could be interesting, it 
> raises several ambiguity questions.  For example, we need significant 
> lookahead to realize that “a” here is not a trailing closure, since we have a 
> closure expression being fully applied after it:
> 
>       if foo { …a... } { …b… }()
> 
> this could be addressed with whitespace rules or other approaches, but since 
> any such direction would be compatible with this proposal, I see it as a 
> separable potential extension on top of this basic proposal.
> 
> Change the syntax of guard: I only list this for completeness, but we could 
> eliminate the `else` keyword, making guard more similar to `if` and `while`.  
> I personally think that this is a really bad idea though: the guard statement 
> is not a general `unless` statement, and its current syntax was very very 
> carefully evaluated, iterated on, discussed, and re-evaluated in the Swift 2 
> timeframe.  I feel that it has stood the test of time well since then.
> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to