I would be fine with this! Ambiguity like this not only makes it hard for the 
compiler, but for the reader too.


> On 28 May 2016, at 6:10 PM, David Hart via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 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 
>> <swift-evolution@swift.org> 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
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to