Could we just require "let" (or var) to introduce every binding, rather than allowing the combination "if let x = y, z = q, ..."? I always use "let" anyway; I think it's easier to read.
On Tue, May 24, 2016 at 11:42 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Okay, and here is where the problem is (thanks Chris L)
`z = q` is an expression. It returns Void.
where q is non-optional, there's issues in that `q` is not an optional and `z = q` is an expression.
On May 24, 2016, at 11:59 AM, Austin Zheng <austinzheng@gmail.com <mailto:austinzheng@gmail.com>> wrote:
I like the idea in principle.
However, right now you can write something like:
if let a = optionalA, frob = fooBarBaz() { ... }
It's clear that both clauses are optional binding clauses.
With this change, it's not clear anymore whether the second clause is an optional binding clause, or a logic test erroneously using '=' instead of '=='.
To be fair, though, since assignment in Swift doesn't return the new value as it does in C, there is far less room for disastrous bugs caused by this sort of mistake.
Austin
On Fri, May 20, 2016 at 10:07 AM, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Earlier on Swift Evolution:
Me: "Is there a technical reason that Swift cannot be expanded to allow arbitrary mixes of conditional binding and boolean assertions within a single compound guard statement?"
Joe Groff: "No. You already can, we just have the somewhat strange rule that to separate `guard` conditions uses `,` before optional or pattern conditions, but `where` before Boolean conditions. There's no technical reason we couldn't accept either 'where' or ',' consistently."
guard x == 0,
let y = optional where
z == 2 {
}
Pitch:
I'd like to update Swift's grammar to interchangeably and consistently accept `where` or `,` to separate guard conditions. This would allow a more consistent approach that supports intermingling conditional binding and boolean assertions. Here's a real-world bit of code I was helping someone with a few evenings ago. It's attempting to navigate through some JSON, using optional conditions with where clauses.
guard
let fileContents = fileContents,
let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,
let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count > 0,
let featuresDict = featuresArray[0] as? NSDictionary,
let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count > 0,
let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count > 3
else { fatalError("Reason") }
Each `where` test is a separate test. While there are semantic ties between the conditional binding and the count tests, there doesn't have to be. Under Swift's current rules, you must use the `where` keyword to introduce a Boolean test after a binding or pattern, regardless of whether or not there's an underlying semantic link between the two.
By removing this requirement and allowing interchangeability between `where` and `,`, you're given the option of tying the boolean to the binding/pattern match or introducing a boolean statement with no connection to previous steps. Here's what this example looks like after excluding `where`:
guard
let fileContents = fileContents,
let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,
let featuresArray = jsonDict["features"] as? NSArray,
featuresArray.count > 0,
let featuresDict = featuresArray.firstObject as? NSDictionary,
let coordinatesArray = featuresDict["geometry"],
coordinatesArray.count > 0,
let coordinateArray = coordinatesArray.firstObject as? NSArray,
coordinateArray.count > 3
else { fatalError("Reason") }
The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.
guard
minimumShapeCount > 4,
let shapes = decompose(map, minimum: minimumShapeCount),
availableArea > minimumArea,
let map = placeShapes(shapes, availableArea) else {
fatalError()
}
would be allowed compared to current Swift which mandates where between the second and third tests:
let shapes = decompose(map, minimum: minimumShapeCount) where availableArea > minimumArea,
In my vision, Swift would continue to allow where clauses and expand to allow disjoint Boolean entries.
Thoughts?
-- E
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution