# \[Pitch\] making where and , interchangeable in guard conditions.

**URL:** <https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702>\
**Category:** Pitches\
**Created:** [May 20, 2016, 5:07pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702 "2016-05-20T17:07:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 20, 2016, 5:07pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/1 "2016-05-20T17:07:22Z")

</div>

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."

&nbsp;&nbsp;guard x == 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
&nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
&nbsp;&nbsp;}

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  
&nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
&nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
&nbsp;&nbsp;&nbsp;&nbsp;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  
&nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
&nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
&nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
&nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
&nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
&nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }

The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.

guard  
&nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
&nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
&nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
&nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
}

would be allowed compared to current Swift which mandates where between the second and third tests:

&nbsp;&nbsp;&nbsp;&nbsp;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

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [May 20, 2016, 5:45pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/2 "2016-05-20T17:45:02Z")

</div>

I agree `guard let y = optional where z == 2` reads quite strangely.

To me, though, it could make sense if variables bound in a guard statement  
are restricted to a boolean assertion only after a `where`, but unrelated  
boolean assertions should definitely not require it (i.e. `guard let y =  
optional where y == 2` does seem more sensible than `guard let y =  
optional, y == 2`, but `guard let y = optional where z == 2` is unpleasant.)

> **···**
>
> On Fri, May 20, 2016 at 12:07 PM, Erica Sadun via swift-evolution \< 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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray \*where \*\*featuresArray.count  
> > \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] \*where \*\*coordinatesArray.count  
> > \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray \*where \*\*coordinateArray.count  
> > \> 3\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > \* featuresArray.count \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > \* coordinatesArray.count \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;\*coordinateArray.count \> 3\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > 
> > The motivation for this approach becomes more compelling when the Boolean  
> > tests are disjoint from binding or pattern matches.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between  
> > the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [May 20, 2016, 5:53pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/3 "2016-05-20T17:53:57Z")

</div>

> 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."
> 
> &nbsp;&nbsp;guard x == 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
> &nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
> &nbsp;&nbsp;}
> 
> 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  
> &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
> &nbsp;&nbsp;&nbsp;&nbsp;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  
> &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> &nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> &nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> &nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
> &nbsp;&nbsp;&nbsp;&nbsp;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  
&nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
&nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray  
&nbsp;&nbsp;&nbsp;&nbsp;where featuresArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry”]  
&nbsp;&nbsp;&nbsp;&nbsp;where coordinatesArray.count \> 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray  
&nbsp;&nbsp;&nbsp;&nbsp;where coordinateArray.count \> 3  
&nbsp;&nbsp;&nbsp;&nbsp;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.

> **···**
>
> > On May 20, 2016, at 12:07 PM, Erica Sadun via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![L\_Mihalkovic](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/l_mihalkovic/32/5802_2.png) [@L\_Mihalkovic](https://forums.swift.org/u/L_Mihalkovic)\
**Post date:** [May 20, 2016, 5:38pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/4 "2016-05-20T17:38:47Z")

</div>

> 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."
> 
> &nbsp;&nbsp;guard x == 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
> &nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
> &nbsp;&nbsp;}
> 
> 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  
> &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
> &nbsp;&nbsp;&nbsp;&nbsp;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  
> &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> &nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> &nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
> &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> &nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
> &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }

I have mixed thoughts about it. The former perl swchartzian-transform fan loves it, and the more responsible high speed trading systems developer finds it the kind of look-it-works-without-the-hands code i am not typically eager to see people do in my teams.  
The apache spark project is a great example of a widely popular scala project that succeeded because it banned the kind of back-breaking areobatics that compilers can make sense of and normal (i.e not overly expensive and reasonably productive) developers typically get tangled in.

> **···**
>
> > On May 20, 2016, at 7:07 PM, Erica Sadun via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Krystof\_Vasa](https://avatars.discourse-cdn.com/v4/letter/k/e99b99/32.png) [@Krystof\_Vasa](https://forums.swift.org/u/Krystof_Vasa)\
**Post date:** [May 20, 2016, 5:40pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/5 "2016-05-20T17:40:51Z")

</div>

+1 for me. Been longing for something like this myself this actually.

> **···**
>
> > On May 20, 2016, at 7:07 PM, Erica Sadun via swift-evolution \<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."
> > 
> > &nbsp;&nbsp;guard x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
> > &nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
> > &nbsp;&nbsp;}
> > 
> > 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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > &nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > 
> > The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Austin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/austin/32/1196_2.png) [@Austin](https://forums.swift.org/u/Austin)\
**Post date:** [May 24, 2016, 5:59pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/6 "2016-05-24T17:59:20Z")

</div>

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\> 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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray \*where \*\*featuresArray.count  
> > \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] \*where \*\*coordinatesArray.count  
> > \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray \*where \*\*coordinateArray.count  
> > \> 3\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > \* featuresArray.count \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > \* coordinatesArray.count \> 0,\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;\*coordinateArray.count \> 3\*  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > 
> > The motivation for this approach becomes more compelling when the Boolean  
> > tests are disjoint from binding or pattern matches.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between  
> > the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 20, 2016, 6:01pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/7 "2016-05-20T18:01:21Z")

</div>

That's kind of the heart of the matter.

There's an assumption that guard statements are:

`guard` (conjoined boolean tests) | (conjoined boolean tests,)? (pattern | binding (where boolean)?, )+ else {...}

Right? (Except I couldn't figure out how to grammar out the final comma,) I'm suggesting:

`guard` ((boolean | (pattern | binding (where boolean)?)),)+ else {...}

instead. (And ditto about final comma) This promotes boolean statements to the same standing, so they're not limited to the start of the guard statement or syntactically tied to a pattern/binding where there may be no semantic basis.

-- E

> **···**
>
> > On May 20, 2016, at 11:53 AM, Matthew Johnson \<matthew@anandabits.com\> wrote:  
> > 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.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [May 20, 2016, 6:12pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/8 "2016-05-20T18:12:02Z")

</div>

> > 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.
> 
> That's kind of the heart of the matter.
> 
> There's an assumption that guard statements are:
> 
> `guard` (conjoined boolean tests) | (conjoined boolean tests,)? (pattern | binding (where boolean)?, )+ else {...}
> 
> Right? (Except I couldn't figure out how to grammar out the final comma,) I'm suggesting:
> 
> `guard` ((boolean | (pattern | binding (where boolean)?)),)+ else {...}
> 
> instead. (And ditto about final comma) This promotes boolean statements to the same standing, so they're not limited to the start of the guard statement or syntactically tied to a pattern/binding where there may be no semantic basis.

Yep, I know. I’m agreeing with breaking the syntactic tie to pattern binding, just questioning whether we should drop the need to introduce subsequent ones with `where`. I am on the fence as to which is more readable and interested in hearing discussion about that.

This is what it would look like if drop the requirement that they be tied to a pattern binding but we require `where` on subsequent boolean expressions (meaning each clause is introduced with a keyword.

`guard` (boolean,)? (((where boolean) | (pattern | binding (where boolean)?)),)+ else {…}

We could also do this if we wanted to allow all boolean expressions, even the first, to be introduced with `where` to support consistent formatting of all clauses in a multi-line construct like the ones in your example.

`guard` (where? boolean,)? (((where boolean) | (pattern | binding (where boolean)?)),)+ else {...}

> **···**
>
> > On May 20, 2016, at 1:01 PM, Erica Sadun \<erica@ericasadun.com\> wrote:
> > 
> > > On May 20, 2016, at 11:53 AM, Matthew Johnson \<matthew@anandabits.com \<mailto:matthew@anandabits.com\>\> wrote:
> 
> > -- E

---

<div class="post-metadata">

**Author:** ![L\_Mihalkovic](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/l_mihalkovic/32/5802_2.png) [@L\_Mihalkovic](https://forums.swift.org/u/L_Mihalkovic)\
**Post date:** [May 20, 2016, 6:15pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/9 "2016-05-20T18:15:59Z")

</div>

> > 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.
> 
> That's kind of the heart of the matter.
> 
> There's an assumption that guard statements are:
> 
> `guard` (conjoined boolean tests) | (conjoined boolean tests,)? (pattern | binding (where boolean)?, )+ else {...}
> 
> Right? (Except I couldn't figure out how to grammar out the final comma,) I'm suggesting:
> 
> `guard` ((boolean | (pattern | binding (where boolean)?)),)+ else {...}
> 
> instead. (And ditto about final comma) This promotes boolean statements to the same standing, so they're not limited to the start of the guard statement or syntactically tied to a pattern/binding where there may be no semantic basis.
> 
> -- E

GRAMMAR OF A GUARD STATEMENT

\<\>guard-statement → guard­condition-clause \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/condition-clause&gt;­else­code\-block](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-clause&gt;%C2%ADelse%C2%ADcode%5C-block) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/code-block&gt;%C2%AD)  
\<\>condition-clause → expression \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD)  
\<\>condition-clause → expression \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD,%C2%ADcondition%5C-list) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
\<\>condition-clause → condition-list \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
\<\>condition-clause → availability-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/availability-condition&gt;%C2%AD,%C2%ADexpression) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD)  
\<\>condition-list → condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition&gt;%C2%AD) condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition&gt;%C2%AD,%C2%ADcondition%5C-list) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
\<\>condition → availability-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/availability-condition&gt;%C2%AD) case-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/case-condition&gt;%C2%AD) optional-binding-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/optional-binding-condition&gt;%C2%AD)  
\<\>case-condition → case­pattern \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html#//apple_ref/swift/grammar/pattern&gt;%C2%ADinitializer) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/initializer&gt;%C2%ADwhere%5C-clause) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/where-clause&gt;%C2%ADopt%C2%AD)

it is all shared at the moment.

/// stmt-guard:  
/// 'guard' condition 'else' stmt-brace  
///  
ParserResult\<Stmt\> Parser::parseStmtGuard() {  
&nbsp;&nbsp;SourceLoc GuardLoc = consumeToken(tok::kw\_guard);  
&nbsp;&nbsp;  
...

I guess it means that stepping out of what it currently does is straightforward to isolate from side effects, but likely a significant piece of work if it is not make a superset (meaning that bits and parts or the way the current grammar is structured can be reused in the manner they are today) of what it is today.

> **···**
>
> > On May 20, 2016, at 8:01 PM, Erica Sadun via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > > On May 20, 2016, at 11:53 AM, Matthew Johnson \<matthew@anandabits.com \<mailto:matthew@anandabits.com\>\> wrote:
> 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 6:19pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/10 "2016-05-24T18:19:29Z")

</div>

Right now, if you look at the grammar, it's pretty hard to follow and special cased.  
I think if people follow an intentional pattern of a condition per line (including where clauses)  
they won't get in trouble. (Also Swift is a lot smarter about inadvertent = vs ==)

-- E

> **···**
>
> > On May 24, 2016, at 11:59 AM, Austin Zheng \<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

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 6:42pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/11 "2016-05-24T18:42:34Z")

</div>

Okay, and here is where the problem is (thanks Chris L)

`z = q` is an expression. It returns Void.

For example:

let q = 5  
var z = 0  
let foo = z = q // foo inferred to have type `()` which may be unexpected

So if you have the following statement:

guard let x = optional, z = q else {...}

where q is non-optional, there's issues in that `q` is not an optional and `z = q` is an expression.

-- E

> **···**
>
> > On May 24, 2016, at 11:59 AM, Austin Zheng \<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."
> > 
> > &nbsp;&nbsp;guard x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
> > &nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
> > &nbsp;&nbsp;}
> > 
> > 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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
> > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > &nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > &nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > 
> > The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > }
> > 
> > would be allowed compared to current Swift which mandates where between the second and third tests:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;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](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 2:30pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/12 "2016-05-24T14:30:46Z")

</div>

> GRAMMAR OF A GUARD STATEMENT
> 
> \<\>guard-statement → guard­condition-clause \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/condition-clause&gt;­else­code\-block](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-clause&gt;%C2%ADelse%C2%ADcode%5C-block) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/code-block&gt;%C2%AD)  
> \<\>condition-clause → expression \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Expressions.html#//apple\_ref/swift/grammar/expression&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD)  
> \<\>condition-clause → expression \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Expressions.html#//apple\_ref/swift/grammar/expression&gt;­,­condition\-list](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD,%C2%ADcondition%5C-list) \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/condition-list&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
> \<\>condition-clause → condition-list \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/condition-list&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
> \<\>condition-clause → availability-condition \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/availability-condition&gt;­,­expression](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/availability-condition&gt;%C2%AD,%C2%ADexpression) \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Expressions.html#//apple\_ref/swift/grammar/expression&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/expression&gt;%C2%AD)  
> \<\>condition-list → condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition&gt;%C2%AD) condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition&gt;%C2%AD,%C2%ADcondition%5C-list) \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/condition-list&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/condition-list&gt;%C2%AD)  
> \<\>condition → availability-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/availability-condition&gt;%C2%AD) case-condition \<[https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift\_Programming\_Language/Statements.html#//apple\_ref/swift/grammar/case-condition&gt;­](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/case-condition&gt;%C2%AD) optional-binding-condition \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/optional-binding-condition&gt;%C2%AD)  
> \<\>case-condition → case­pattern \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html#//apple_ref/swift/grammar/pattern&gt;%C2%ADinitializer) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/initializer&gt;%C2%ADwhere%5C-clause) \<[The Swift Programming Language: Redirect](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/where-clause&gt;%C2%ADopt%C2%AD)

While the easiest solution allows commas interchangeably with `where`, it would allow construction of statements like this and  
it wouldn't introduce the ability to mix and match Boolean expressions, availability conditions, case conditions, and optional binding conditions.

// where-clause → (where | ,) where-expression  
for i in 0...10, i % 2 == 0 { print(i) }

To get that you need:

‌condition-list → condition | expression | condition , condition-list | expression, condition-list

Which means that `guard` would be redefined to:

guard condition-list else code-block

This would affect `while`, `repeat-while`, `if`, and `guard`.

-- E

---

<div class="post-metadata">

**Author:** ![jtbandes](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jtbandes/32/463_2.png) [@jtbandes](https://forums.swift.org/u/jtbandes)\
**Post date:** [May 24, 2016, 6:47pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/13 "2016-05-24T18:47:05Z")

</div>

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\> wrote:
> 
> > Okay, and here is where the problem is (thanks Chris L)
> > 
> > `z = q` is an expression. It returns Void.
> > 
> > For example:
> > 
> > let q = 5  
> > var z = 0  
> > let foo = z = q // foo inferred to have type `()` which may be unexpected
> > 
> > So if you have the following statement:
> > 
> > guard let x = optional, z = q else {...}
> > 
> > where q is non-optional, there's issues in that `q` is not an optional and  
> > `z = q` is an expression.
> > 
> > -- E
> > 
> > On May 24, 2016, at 11:59 AM, Austin Zheng \<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\> 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  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > > NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray \*where \*\*featuresArray.count  
> > > \> 0,\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] \*where \*\*coordinatesArray.count  
> > > \> 0,\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray \*where \*\*coordinateArray.count  
> > > \> 3\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try  
> > > NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as?  
> > > NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > > \* featuresArray.count \> 0,\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > > \* coordinatesArray.count \> 0,\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\*coordinateArray.count \> 3\*  
> > > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > > 
> > > The motivation for this approach becomes more compelling when the Boolean  
> > > tests are disjoint from binding or pattern matches.
> > > 
> > > guard  
> > > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > > }
> > > 
> > > would be allowed compared to current Swift which mandates where between  
> > > the second and third tests:
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 6:57pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/14 "2016-05-24T18:57:58Z")

</div>

Or you can make sure every expression is boolean, which would take care of this as well...

-- E

> **···**
>
> > On May 24, 2016, at 12:47 PM, Jacob Bandes-Storch \<jtbandes@gmail.com\> wrote:
> > 
> > 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.
> > 
> > For example:
> > 
> > let q = 5  
> > var z = 0  
> > let foo = z = q // foo inferred to have type `()` which may be unexpected
> > 
> > So if you have the following statement:
> > 
> > guard let x = optional, z = q else {...}
> > 
> > where q is non-optional, there's issues in that `q` is not an optional and `z = q` is an expression.
> > 
> > -- E
> > 
> > > 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."
> > > 
> > > &nbsp;&nbsp;guard x == 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where  
> > > &nbsp;&nbsp;&nbsp;&nbsp;z == 2 {  
> > > &nbsp;&nbsp;}
> > > 
> > > 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  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray where featuresArray.count \> 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray[0] as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"] where coordinatesArray.count \> 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray[0] as? NSArray where coordinateArray.count \> 3  
> > > &nbsp;&nbsp;&nbsp;&nbsp;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  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let fileContents = fileContents,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: ) as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresArray = jsonDict["features"] as? NSArray,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;featuresArray.count \> 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let featuresDict = featuresArray.firstObject as? NSDictionary,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinatesArray = featuresDict["geometry"],  
> > > &nbsp;&nbsp;&nbsp;&nbsp;coordinatesArray.count \> 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let coordinateArray = coordinatesArray.firstObject as? NSArray,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;coordinateArray.count \> 3  
> > > &nbsp;&nbsp;&nbsp;&nbsp;else { fatalError("Reason") }
> > > 
> > > The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.
> > > 
> > > guard  
> > > &nbsp;&nbsp;&nbsp;&nbsp;minimumShapeCount \> 4,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let shapes = decompose(map, minimum: minimumShapeCount),  
> > > &nbsp;&nbsp;&nbsp;&nbsp;availableArea \> minimumArea,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let map = placeShapes(shapes, availableArea) else {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatalError()  
> > > }
> > > 
> > > would be allowed compared to current Swift which mandates where between the second and third tests:
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 3:10pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/15 "2016-05-24T15:10:00Z")

</div>

Draft: [clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160)

Simplifying condition clauses and intermingling expressions with other conditions

Proposal: TBD  
Author: Erica Sadun \<[https://github.com/erica&gt](https://github.com/erica&gt);  
Status: TBD  
Review manager: TBD  
\<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#introduction&gt;Introduction)

This proposal adjust Swift grammar to enable the arbitrary mix of expressions among conditions rather than constraining them before other conditions. Under this proposal, expressions are no longer limited to where clauses after the initial list of Boolean conditions.

Swift-evolution thread: [Pitch] making where and , interchangeable in guard conditions \<[http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt](http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt);  
\<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#motivation&gt;Motivation)

There is no technical reason to disallow arbitrary mixes of binding, patterns, availability tests, and Boolean assertions within a single compound condition clause. Swift currently enforces a grammar that limits expressions to where clauses after the first non-Boolean condition clause has been mentioned. This rule means that all standalone Boolean tests must precede binding and pattern conditions and allows for code such as:

guard  
&nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let y = optional where z == 2  
&nbsp;&nbsp;&nbsp;&nbsp;else { ... }  
In this example, the Boolean z == 2 clause has no semantic relationship to the optional condition to which it's syntactically bound. Ideally, where clauses should be restricted to a Boolean assertion tied to variables connected to the binding or pattern condition. Unrelated Boolean assertions should be allowed to stand on their own

If accepted, the following code would be legal, as would similar usage in while and if statements.

guard  
&nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
&nbsp;&nbsp;&nbsp;&nbsp;let y = optional,  
&nbsp;&nbsp;&nbsp;&nbsp;z == 2  
&nbsp;&nbsp;&nbsp;&nbsp;else { ... }  
\<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#detailed-design&gt;Detailed) Design

Under this proposal, condition lists are updated to accept a grammar along the following lines:

‌condition-list → condition | expression | condition , condition-list | expression, condition-list  
This enables guard, while, repeat-while, and if to adopt grammars like:

guard condition-list else code-block  
while condition-list code-block  
if condition-list code-block (else-clause)?  
Note: A repeat-while statement does not use a condition list. Its grammar is repeat code-block while expression

This approach simplifies the current Swift grammar, which constructs condition clauses separately from condition lists and conditions. This extra work is needed to introduce an expression before condition lists and to allow an expression after availability checks:

condition-clause → expression  
condition-clause → expression , condition-list  
condition-clause → condition-list  
condition-clause → availability-condition , expression  
condition-list → condition | condition,condition-list  
condition → availability-condition | case-condition | optional-binding-condition  
Beyond this high level change, all three conditions (availability conditions, case conditions, and optional binding conditions) remain unaffected as do their associated where clause grammar. This solution changes list construction not whereclauses.

\<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#impact-on-existing-code&gt;Impact) on Existing Code

This proposal does not affect existing code.

\<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#alternatives-considered&gt;Alternatives) Considered

The "easiest" solution that free interchange of commas with where, permits construction of statements like the following:

// where-clause → (where | ,) where-expression  
for i in 0...10, i % 2 == 0 { print(i) }  
Adjusting the where clause in this way wouldn't introduce the ability to mix and match Boolean expressions, availability conditions, case conditions, and optional binding conditions in condition clauses, and is therefore discarded from consideration.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [May 24, 2016, 3:29pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/16 "2016-05-24T15:29:08Z")

</div>

Does this proposal distinguish between "where clauses [...] restricted to a  
Boolean assertion tied to variables connected to the binding or pattern  
condition" and "unrelated Boolean assertions [that] should be allowed to  
stand on their own"?

Or are both types of boolean assertions now permitted either following a  
comma or following a where clause?

> **···**
>
> On Tue, May 24, 2016 at 10:10 Erica Sadun via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Draft: [https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160)
> > 
> > Simplifying condition clauses and intermingling expressions with other  
> > conditions
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: TBD  
> > &nbsp;&nbsp;&nbsp;- Author: Erica Sadun \<[https://github.com/erica&gt](https://github.com/erica&gt);  
> > &nbsp;&nbsp;&nbsp;- Status: TBD  
> > &nbsp;&nbsp;&nbsp;- Review manager: TBD
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#introduction&gt);  
> > Introduction
> > 
> > This proposal adjust Swift grammar to enable the arbitrary mix of  
> > expressions among conditions rather than constraining them before other  
> > conditions. Under this proposal, expressions are no longer limited to where  
> > clauses after the initial list of Boolean conditions.
> > 
> > Swift-evolution thread: [Pitch] making where and , interchangeable in  
> > guard conditions  
> > \<[http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt](http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt);  
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#motivation&gt);  
> > Motivation
> > 
> > There is no technical reason to disallow arbitrary mixes of binding,  
> > patterns, availability tests, and Boolean assertions within a single  
> > compound condition clause. Swift currently enforces a grammar that limits  
> > expressions to where clauses after the first non-Boolean condition clause  
> > has been mentioned. This rule means that all standalone Boolean tests must  
> > precede binding and pattern conditions and allows for code such as:
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where z == 2
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }
> > 
> > In this example, the Boolean z == 2 clause has no semantic relationship  
> > to the optional condition to which it's syntactically bound. Ideally,  
> > where clauses should be restricted to a Boolean assertion tied to  
> > variables connected to the binding or pattern condition. Unrelated Boolean  
> > assertions should be allowed to stand on their own
> > 
> > If accepted, the following code would be legal, as would similar usage in  
> > while and if statements.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional,  
> > &nbsp;&nbsp;&nbsp;&nbsp;z == 2  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#detailed-design&gt;Detailed)  
> > Design
> > 
> > Under this proposal, condition lists are updated to accept a grammar along  
> > the following lines:
> > 
> > ‌condition-list → condition | expression | condition , condition-list | expression, condition-list
> > 
> > This enables guard, while, repeat-while, and if to adopt grammars like:
> > 
> > guard condition-list else code-block  
> > while condition-list code-block  
> > if condition-list code-block (else-clause)?
> > 
> > \*Note: A repeat-while statement does not use a condition list. Its grammar  
> > is repeat code-block while expression\*
> > 
> > This approach simplifies the current Swift grammar, which constructs  
> > condition clauses separately from condition lists and conditions. This  
> > extra work is needed to introduce an expression before condition lists and  
> > to allow an expression after availability checks:
> > 
> > condition-clause → expression  
> > condition-clause → expression , condition-list  
> > condition-clause → condition-list  
> > condition-clause → availability-condition , expression  
> > condition-list → condition | condition,condition-list  
> > condition → availability-condition | case-condition | optional-binding-condition
> > 
> > Beyond this high level change, all three conditions (availability  
> > conditions, case conditions, and optional binding conditions) remain  
> > unaffected as do their associated where clause grammar. This solution  
> > changes list construction not whereclauses.
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#impact-on-existing-code&gt;Impact)  
> > on Existing Code
> > 
> > This proposal does not affect existing code.
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#alternatives-considered&gt;Alternatives)  
> > Considered
> > 
> > The "easiest" solution that free interchange of commas with where,  
> > permits construction of statements like the following:
> > 
> > // where-clause → (where | ,) where-expressionfor i in 0...10, i % 2 == 0 { print(i) }
> > 
> > Adjusting the where clause in this way wouldn't introduce the ability to  
> > mix and match Boolean expressions, availability conditions, case  
> > conditions, and optional binding conditions in condition clauses, and is  
> > therefore discarded from consideration.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 4:57pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/17 "2016-05-24T16:57:06Z")

</div>

There is no way I could figure out how to restrict Boolean assertions to mentioned variables therefore I left where clauses entirely untouched.  
I'd recommend people adopt in-house standards where Boolean assertions in where clauses should be semantically tied to the condition  
clause that introduces them.

I will add this as a note.

-- E

> **···**
>
> > On May 24, 2016, at 9:29 AM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > 
> > Does this proposal distinguish between "where clauses [...] restricted to a Boolean assertion tied to variables connected to the binding or pattern condition" and "unrelated Boolean assertions [that] should be allowed to stand on their own"?
> > 
> > Or are both types of boolean assertions now permitted either following a comma or following a where clause?
> > 
> > On Tue, May 24, 2016 at 10:10 Erica Sadun via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > Draft: [clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160)
> > 
> > Simplifying condition clauses and intermingling expressions with other conditions
> > 
> > Proposal: TBD  
> > Author: Erica Sadun \<[https://github.com/erica&gt](https://github.com/erica&gt);  
> > Status: TBD  
> > Review manager: TBD  
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#introduction&gt;Introduction)
> > 
> > This proposal adjust Swift grammar to enable the arbitrary mix of expressions among conditions rather than constraining them before other conditions. Under this proposal, expressions are no longer limited to where clauses after the initial list of Boolean conditions.
> > 
> > Swift-evolution thread: [Pitch] making where and , interchangeable in guard conditions \<[http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt](http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt);  
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#motivation&gt;Motivation)
> > 
> > There is no technical reason to disallow arbitrary mixes of binding, patterns, availability tests, and Boolean assertions within a single compound condition clause. Swift currently enforces a grammar that limits expressions to where clauses after the first non-Boolean condition clause has been mentioned. This rule means that all standalone Boolean tests must precede binding and pattern conditions and allows for code such as:
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where z == 2
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }  
> > In this example, the Boolean z == 2 clause has no semantic relationship to the optional condition to which it's syntactically bound. Ideally, where clauses should be restricted to a Boolean assertion tied to variables connected to the binding or pattern condition. Unrelated Boolean assertions should be allowed to stand on their own
> > 
> > If accepted, the following code would be legal, as would similar usage in while and if statements.
> > 
> > guard  
> > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional,  
> > &nbsp;&nbsp;&nbsp;&nbsp;z == 2  
> > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }  
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#detailed-design&gt;Detailed) Design
> > 
> > Under this proposal, condition lists are updated to accept a grammar along the following lines:
> > 
> > ‌condition-list → condition | expression | condition , condition-list | expression, condition-list  
> > This enables guard, while, repeat-while, and if to adopt grammars like:
> > 
> > guard condition-list else code-block  
> > while condition-list code-block  
> > if condition-list code-block (else-clause)?  
> > Note: A repeat-while statement does not use a condition list. Its grammar is repeat code-block while expression
> > 
> > This approach simplifies the current Swift grammar, which constructs condition clauses separately from condition lists and conditions. This extra work is needed to introduce an expression before condition lists and to allow an expression after availability checks:
> > 
> > condition-clause → expression  
> > condition-clause → expression , condition-list  
> > condition-clause → condition-list  
> > condition-clause → availability-condition , expression  
> > condition-list → condition | condition,condition-list  
> > condition → availability-condition | case-condition | optional-binding-condition  
> > Beyond this high level change, all three conditions (availability conditions, case conditions, and optional binding conditions) remain unaffected as do their associated where clause grammar. This solution changes list construction not whereclauses.
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#impact-on-existing-code&gt;Impact) on Existing Code
> > 
> > This proposal does not affect existing code.
> > 
> > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#alternatives-considered&gt;Alternatives) Considered
> > 
> > The "easiest" solution that free interchange of commas with where, permits construction of statements like the following:
> > 
> > // where-clause → (where | ,) where-expression  
> > for i in 0...10, i % 2 == 0 { print(i) }  
> > Adjusting the where clause in this way wouldn't introduce the ability to mix and match Boolean expressions, availability conditions, case conditions, and optional binding conditions in condition clauses, and is therefore discarded from consideration.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [May 24, 2016, 5:01pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/18 "2016-05-24T17:01:00Z")

</div>

With the implementation of your proposal, will there be anything that can  
be written in where clauses that cannot be written after a comma (in the  
context of guard statements specifically)? If not, does the where clause  
become entirely a stylistic flourish?

> **···**
>
> On Tue, May 24, 2016 at 11:57 Erica Sadun \<erica@ericasadun.com\> wrote:
> 
> > There is no way I could figure out how to restrict Boolean assertions to  
> > mentioned variables therefore I left where clauses entirely untouched.  
> > I'd recommend people adopt in-house standards where Boolean assertions in  
> > where clauses should be semantically tied to the condition  
> > clause that introduces them.
> > 
> > I will add this as a note.
> > 
> > -- E
> > 
> > On May 24, 2016, at 9:29 AM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > 
> > Does this proposal distinguish between "where clauses [...] restricted to  
> > a Boolean assertion tied to variables connected to the binding or pattern  
> > condition" and "unrelated Boolean assertions [that] should be allowed to  
> > stand on their own"?
> > 
> > Or are both types of boolean assertions now permitted either following a  
> > comma or following a where clause?
> > 
> > On Tue, May 24, 2016 at 10:10 Erica Sadun via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > > Draft: [https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160)
> > > 
> > > Simplifying condition clauses and intermingling expressions with other  
> > > conditions
> > > 
> > > &nbsp;&nbsp;&nbsp;- Proposal: TBD  
> > > &nbsp;&nbsp;&nbsp;- Author: Erica Sadun \<[https://github.com/erica&gt](https://github.com/erica&gt);  
> > > &nbsp;&nbsp;&nbsp;- Status: TBD  
> > > &nbsp;&nbsp;&nbsp;- Review manager: TBD
> > > 
> > > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#introduction&gt);  
> > > Introduction
> > > 
> > > This proposal adjust Swift grammar to enable the arbitrary mix of  
> > > expressions among conditions rather than constraining them before other  
> > > conditions. Under this proposal, expressions are no longer limited to where  
> > > clauses after the initial list of Boolean conditions.
> > > 
> > > Swift-evolution thread: [Pitch] making where and , interchangeable in  
> > > guard conditions  
> > > \<[http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt](http://thread.gmane.org/gmane.comp.lang.swift.evolution/17926&gt);
> > > 
> > > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#motivation&gt);  
> > > Motivation
> > > 
> > > There is no technical reason to disallow arbitrary mixes of binding,  
> > > patterns, availability tests, and Boolean assertions within a single  
> > > compound condition clause. Swift currently enforces a grammar that limits  
> > > expressions to where clauses after the first non-Boolean condition  
> > > clause has been mentioned. This rule means that all standalone Boolean  
> > > tests must precede binding and pattern conditions and allows for code such  
> > > as:
> > > 
> > > guard  
> > > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional where z == 2
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }
> > > 
> > > In this example, the Boolean z == 2 clause has no semantic relationship  
> > > to the optional condition to which it's syntactically bound. Ideally,  
> > > where clauses should be restricted to a Boolean assertion tied to  
> > > variables connected to the binding or pattern condition. Unrelated Boolean  
> > > assertions should be allowed to stand on their own
> > > 
> > > If accepted, the following code would be legal, as would similar usage in  
> > > while and if statements.
> > > 
> > > guard  
> > > &nbsp;&nbsp;&nbsp;&nbsp;x == 0,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let y = optional,  
> > > &nbsp;&nbsp;&nbsp;&nbsp;z == 2  
> > > &nbsp;&nbsp;&nbsp;&nbsp;else { ... }
> > > 
> > > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#detailed-design&gt;Detailed)  
> > > Design
> > > 
> > > Under this proposal, condition lists are updated to accept a grammar  
> > > along the following lines:
> > > 
> > > ‌condition-list → condition | expression | condition , condition-list | expression, condition-list
> > > 
> > > This enables guard, while, repeat-while, and if to adopt grammars like:
> > > 
> > > guard condition-list else code-block  
> > > while condition-list code-block  
> > > if condition-list code-block (else-clause)?
> > > 
> > > \*Note: A repeat-while statement does not use a condition list. Its  
> > > grammar is repeat code-block while expression\*
> > > 
> > > This approach simplifies the current Swift grammar, which constructs  
> > > condition clauses separately from condition lists and conditions. This  
> > > extra work is needed to introduce an expression before condition lists and  
> > > to allow an expression after availability checks:
> > > 
> > > condition-clause → expression  
> > > condition-clause → expression , condition-list  
> > > condition-clause → condition-list  
> > > condition-clause → availability-condition , expression  
> > > condition-list → condition | condition,condition-list  
> > > condition → availability-condition | case-condition | optional-binding-condition
> > > 
> > > Beyond this high level change, all three conditions (availability  
> > > conditions, case conditions, and optional binding conditions) remain  
> > > unaffected as do their associated where clause grammar. This solution  
> > > changes list construction not whereclauses.
> > > 
> > > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#impact-on-existing-code&gt;Impact)  
> > > on Existing Code
> > > 
> > > This proposal does not affect existing code.
> > > 
> > > \<[clauses.md · GitHub](https://gist.github.com/erica/74cfee56a597c0e0026a90ee4e49f160#alternatives-considered&gt;Alternatives)  
> > > Considered
> > > 
> > > The "easiest" solution that free interchange of commas with where,  
> > > permits construction of statements like the following:
> > > 
> > > // where-clause → (where | ,) where-expressionfor i in 0...10, i % 2 == 0 { print(i) }
> > > 
> > > Adjusting the where clause in this way wouldn't introduce the ability to  
> > > mix and match Boolean expressions, availability conditions, case  
> > > conditions, and optional binding conditions in condition clauses, and is  
> > > therefore discarded from consideration.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [May 24, 2016, 5:31pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/19 "2016-05-24T17:31:15Z")

</div>

> The where clause is not a stylistic flourish because it is still best used to constrain conditions that are semantically  
> related to conditions. Upon acceptance as now, there are no compiler checks that mandate any relationship.

From a semantic perspective, at least, 'where' and ',' don't really matter to the compiler. Either one is an "and" composition of the list conditions.

-Joe

> **···**
>
> > On May 24, 2016, at 10:07 AM, Erica Sadun \<erica@ericasadun.com\> wrote:
> 
> > The difference is that (1) coders will be allowed to move Boolean assertions out of where clauses when there is no  
> > relationship, and (2) they will be allowed to order the statements as desired. Under the current system, all boolean  
> > clauses must be conjoined and expressed as the first item of the list (except after availability clauses, as the one exception)
> > 
> > -- E
> > 
> > > On May 24, 2016, at 11:01 AM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > > 
> > > With the implementation of your proposal, will there be anything that can be written in where clauses that cannot be written after a comma (in the context of guard statements specifically)? If not, does the where clause become entirely a stylistic flourish?  
> > > On Tue, May 24, 2016 at 11:57 Erica Sadun \<erica@ericasadun.com\> wrote:  
> > > There is no way I could figure out how to restrict Boolean assertions to mentioned variables therefore I left where clauses entirely untouched.  
> > > I'd recommend people adopt in-house standards where Boolean assertions in where clauses should be semantically tied to the condition  
> > > clause that introduces them.
> > > 
> > > I will add this as a note.
> > > 
> > > -- E
> > > 
> > > > On May 24, 2016, at 9:29 AM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > > > 
> > > > Does this proposal distinguish between "where clauses [...] restricted to a Boolean assertion tied to variables connected to the binding or pattern condition" and "unrelated Boolean assertions [that] should be allowed to stand on their own"?
> > > > 
> > > > Or are both types of boolean assertions now permitted either following a comma or following a where clause?

---

<div class="post-metadata">

**Author:** ![Erica\_Sadun](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/erica_sadun/32/243_2.png) [@Erica\_Sadun](https://forums.swift.org/u/Erica_Sadun)\
**Post date:** [May 24, 2016, 5:07pm UTC](https://forums.swift.org/t/pitch-making-where-and-interchangeable-in-guard-conditions/2702/20 "2016-05-24T17:07:35Z")

</div>

The where clause is not a stylistic flourish because it is still best used to constrain conditions that are semantically  
related to conditions. Upon acceptance as now, there are no compiler checks that mandate any relationship.

The difference is that (1) coders will be allowed to move Boolean assertions out of where clauses when there is no  
relationship, and (2) they will be allowed to order the statements as desired. Under the current system, all boolean  
clauses must be conjoined and expressed as the first item of the list (except after availability clauses, as the one exception)

-- E

> **···**
>
> > On May 24, 2016, at 11:01 AM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > 
> > With the implementation of your proposal, will there be anything that can be written in where clauses that cannot be written after a comma (in the context of guard statements specifically)? If not, does the where clause become entirely a stylistic flourish?  
> > On Tue, May 24, 2016 at 11:57 Erica Sadun \<erica@ericasadun.com \<mailto:erica@ericasadun.com\>\> wrote:  
> > There is no way I could figure out how to restrict Boolean assertions to mentioned variables therefore I left where clauses entirely untouched.  
> > I'd recommend people adopt in-house standards where Boolean assertions in where clauses should be semantically tied to the condition  
> > clause that introduces them.
> > 
> > I will add this as a note.
> > 
> > -- E
> > 
> > > On May 24, 2016, at 9:29 AM, Xiaodi Wu \<xiaodi.wu@gmail.com \<mailto:xiaodi.wu@gmail.com\>\> wrote:
> > > 
> > > Does this proposal distinguish between "where clauses [...] restricted to a Boolean assertion tied to variables connected to the binding or pattern condition" and "unrelated Boolean assertions [that] should be allowed to stand on their own"?
> > > 
> > > Or are both types of boolean assertions now permitted either following a comma or following a where clause?
