>> On May 27, 2016, at 5:30 PM, Erica Sadun via swift-evolution >> <[email protected]> wrote: >> >> >>> On May 27, 2016, at 6:26 PM, Brent Royal-Gordon <[email protected]> >>> wrote: >>> >>>> guard >>>> x == 0 && a == b && c == d && >>>> let y = optional, w = optional2, v = optional 3 && >>>> z == 2 >>>> else { ... } >>>> >>>> Figuring out where to break the first line into expression and into >>>> condition (after the `d`) could be very challenging to the compiler. >>> >>> I'm not sure it is. `let` and `case` are not valid in an expression, so an >>> `&&` followed by `let` or `case` must be joining clauses. On the other side >>> of things, Swift's `&&` doesn't ever produce an optional, so if we're >>> parsing an expression at the top level of an if-let, an `&&` must indicate >>> the end of the clause. An if-case *could* theoretically include an `&&`, >>> but pattern matching against a boolean value seems like a fairly useless >>> thing to do in a context that's specifically intended to test booleans. >> >> 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. >> >> -- E
In reality I often write if/guard statements using && exactly the way Brent proposes, only to go back and rework it for syntax correctness. I started this message intending to argue for Brent’s proposal but I think I’ve talked myself out of it :) > On May 28, 2016, at 10:26 AM, Chris Lattner via swift-evolution > <[email protected]> wrote: > >> >> My suggestion would be to reuse our normal && operator: >> >> guard >> x == 0 && >> let y = optional && >> z == 2 >> else { ... } >> >> This would obviously be a built-in `&&` separate from our existing, infix >> operator `&&`. > > Yes, this is technically feasible, but it has the opposite problem from the > above: && is very closely associated (in terms of programmer mindspace) with > boolean conditionals, and the let/case clauses are *not* boolean conditions. I initially didn't think && represents a problem, but I realized as I was working on this message there definitely is a serious issue: ||. I don’t see how you can work around it either and that seems to kill the idea of using && no matter how you slice it. guard x == 0 && let y = optional || z == 2 && y == 5 //is y optional or not?!? else { … } You can’t have the optional let binding shortcut and use boolean values this way. You’d have to figure out if the expression always requires “y = optional” to succeed, then y’s type would be non-optional, otherwise y would be optional. That seems surprising and confusing. What I really want is commas to separate different kinds of clauses because many cases read cleaner as a single line and C ruined semicolons for me, especially their use in for statements. > > The ambiguity is between “case” and “let” conditions, specifically because > “case” takes a pattern, and “let” is a valid pattern: > > guard (pattern1) = expr1, let x = expr2 else > > can be: > > guard (pattern1) = expr1, let (x) = expr2 else > > or: > > guard (pattern1) = expr1, (let x) = expr2 else I am probably missing something but why is this the case? In all of these forms the let is unambiguous; it either precedes the enum case or pattern (itself enclosed in parens), or the let is contained in the parens. if case let .Point(x, y) = value, let z = optional { } if case let (x, y) = value, let z = optional { } if case .Point(let x, _) = value, let z = optional { } if case (let x, 1.0) = value where x != 0.0, let z = optional { } Russ _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
