> On May 20, 2016, at 12:07 PM, Erica Sadun via swift-evolution
> <[email protected]> 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.
You can already format the code in a pretty similar way although it is slightly
awkward because some lines are required to have commas and others must *not*
have commas:
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") }
I agree that it would be good to allow boolean expressions to be stand alone
clauses in order to support formatting like this without the inconsistency with
regards to commas.
I am less certain about allowing simple boolean expressions that are not
introduced by the `where` keyword (excepting the first one which is introduced
with the `guard` keyword). I think this is a separate question that should
receive independent consideration. I think a reasonable argument can be made
both ways.
Also, looking at these examples I can’t help but notice a another case of a
comma separated list that would benefit from allowing newline to be used in
place of the commas as well.
>
> 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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution