> On 23 Mar 2016, at 12:27, Ilya Belenkiy via swift-evolution > <[email protected]> wrote: > > +1, a very useful change. I'd use it in lots of places in my code. > > On Wed, Mar 23, 2016 at 2:03 AM Chris Lattner via swift-evolution > <[email protected] <mailto:[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: > > > > > 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] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
