Yet another alternative: would it be possible to disallow commas as variable 
declaration separators and use them for condition clause separators again:

let a = 4, b = 8 // becomes illegal and requires to separate them on two lines

if a > 4, let c = foo(), let d = bar(), c != d { // now comma is not ambiguous 
anymore
}

David.

> On 28 May 2016, at 08:25, Brent Royal-Gordon via swift-evolution 
> <[email protected]> wrote:
> 
>> Let me answer in another way that speaks to my background which isn't in 
>> compiler theory: The use of && may produce cognitive overload between the 
>> use in Boolean assertions and the use in separating condition clauses.
> 
> Yes, which is quite intentional on my part. The `if` statement requires that 
> all of its clauses succeed; if pattern matching and optional testing were 
> boolean expressions, you would use `&&` to link them with each other and with 
> boolean tests. The fact that these are *not* boolean expressions is a mere 
> artifact of Swift's implementation.
> 
> I think our best solution is to make Swift act as though these *are* boolean 
> expressions, but ones that can only be used in a limited way: they can only 
> be `&&`ed, because they bind variables that have to be made available in 
> specific blocks. In other words, I think we should paper over the compiler 
> limitations preventing these things from working as expected.
> 
> (Actually, it might be interesting to allow `!let` and `!case` statements 
> which are available in the `else` branches of the control structures they're 
> used in, but that's a different story...)
> 
> ***
> 
> If you'll permit me to go sort of "mad dream" here for a moment, I can 
> actually sort of see a way to do a lot of this in the standard library. 
> Imagine if the `let` and `case` clauses in a conditional produced a type like 
> this:
> 
>       enum PatternMatchingResult<BoundValues> {
>               case failed
>               case succeeded (BoundValues)
>       }
> 
> `BoundValues` would be the values, if any, extracted through the pattern 
> matching operation. Then you could define operators like these:
> 
>       func && <T, U>(lhs: PatternMatchingResult<T>, rhs: @autoclosure () -> 
> PatternMatchingResult<U>) -> PatternMatchingResult<(T, U)> {
>               guard case .succeeded (let lhsValue) = lhs else {
>                       return .failed
>               }
>               guard case .succeeded (let rhsValue) = rhs() else {
>                       return .failed
>               }
>               return .succeeded (lhsValue, rhsValue)
>       }
> 
>       func && <T>(lhs: PatternMatchingResult<T>, rhs: @autoclosure () -> 
> Boolean) -> PatternMatchingResult<T> {
>               guard case .succeeded = lhs else {
>                       return .failed
>               }
>               guard rhs() else {
>                       return .failed
>               }
>               return lhs
>       }
>       
>       func && <U>(lhs: Boolean, rhs: @autoclosure () -> 
> PatternMatchingResult<U>) -> PatternMatchingResult<U> {
>               guard lhs else {
>                       return .failed
>               }
>               return rhs()
>       }
> 
> And then transform this:
> 
>       guard
>               x == 0 && a == b && c == d &&
>               let y = optional, w = optional2, v = optional 3 &&
>               z == 2
>       else { ... }
> 
> Into something like this (where `?` is a sort of "anonymous capture slot"):
> 
>       guard case let .success (y, w, v) = (
>               x == 0 && a == b && c == d &&
>               Pattern(.some(?), .some(?), .some(?)).result(ofMatchingAgainst: 
> (optional, optional2, optional3)) &&
>               z == 2
>       )
>       else { ... }
> 
> Resolving to:
> 
>       guard case let PatternMatchingResult.success (y, w, v) = (
>               (&&)(   // (Boolean, PatternMatchingResult) -> 
> PatternMatchingResult
>                       x == 0,
>                       (&&)(   // (Boolean, PatternMatchingResult) -> 
> PatternMatchingResult
>                               a == b,
>                               (&&)(   // (Boolean, PatternMatchingResult) -> 
> PatternMatchingResult
>                                       c == d,
>                                       (&&)(   // (PatternMatchingResult, 
> Boolean) -> PatternMatchingResult
>                                               Pattern(.some(?), .some(?), 
> .some(?)).result(ofMatchingAgainst: (optional, optional2, optional3)),
>                                               z == 2
>                                       )
>                               )
>                       )
>               )
>       )
>       else { ... }
> 
> The `Pattern` type shown here is notional, not an actual thing that would 
> exist as a first-class entity—although that *would* be rather nice to have 
> eventually...
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> 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