<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jun 10, 2016 at 2:10 PM, Brent Royal-Gordon via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; Unlike in switch statements and do loops, a for-in loop&#39;s where-clause is separated from the pattern it modifies.<br>
<br>
</span>(I think &quot;do loops&quot; is supposed to be &quot;do-catch statements&quot;?)<br>
<span class=""><br>
&gt; for case? pattern in expression where-clause? code-block<br>
&gt;<br>
&gt; case-item-list → pattern where-clause? | pattern where-clause? , case-item-list<br>
&gt;<br>
&gt; catch pattern? where-clause? code-block<br>
&gt;<br>
&gt; This separation makes the clause harder to associate with the pattern, can confuse users as to whether it modifies the expression or the pattern, and represents an inconsistency in Swift&#39;s grammar. This proposal regularizes the grammar to match other uses.<br>
<br>
</span>I&#39;m definitely in favor of this. (I should be—I&#39;m listed as coauthor.)<br>
<br>
While I&#39;ve never struggled with the `where` clause—I always assumed it was a filter—it never read right to me. This way does. When I say it out loud, &quot;for x where x less than 10 in numbers&quot; simply seems *far* easier to understand than &quot;for x in numbers where x less than 10&quot;. There&#39;s something about the way the &quot;where&quot; combines with &quot;for&quot; that clarifies the entire statement.<br>
<br>
I also think this better matches the grammar of the `case` statements in a `switch`. Erica quotes the formal grammar above, but you can actually see this in running code: in a `switch` statement, a compound case with a `where` clause like:<br>
<br>
        case .foo, .bar where baz():<br>
<br>
Only applies the `where` clause to the last pattern (.bar, but not .foo). That&#39;s because the rule is that the `where` belongs to the *pattern*, not the entire statement.<br>
<br>
As a question of the proposal&#39;s drafting—as opposed to the feature being proposed—I do think that we should include an example of code before and after the change. The isOdd example ought to do.<br>
<span class=""><br>
&gt; Note where clauses in case conditions and optional bindings have been removed in SE-0099.<br>
<br>
</span>I think there&#39;s actually a case to be made (no pun intended) for bringing `where` back in case conditions, but with an analogous movement of the clause&#39;s position. In other words, where (post-SE-0099) we have this production:<br>
<br>
        case-condition → &quot;case&quot; pattern initializer<br>
<br>
We would change it to:<br>
<br>
        case-condition → &quot;case&quot; pattern where-clause? initializer<br>
<br>
In use, this would look like:<br>
<br>
        if case .some(let Point.cartesian(x, y)) where x &lt; y = json[&quot;rect&quot;]?[&quot;origin&quot;].flatMap(.init(rawValue:)) { … }<br></blockquote><div><br></div><div>I&#39;m concerned here about the `x &lt; y = json...` part of this, if not for the parser then for the human reader. I like the thought in principle though.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Of course, the above could equally be written without a `where` clause:<br>
<br>
        if case .some(let Point.cartesian(x, y)) = json[&quot;rect&quot;]?[&quot;origin&quot;].flatMap(.init(rawValue:)), x &lt; y { … }<br>
<br>
But nevertheless, I think it&#39;s a good idea. Why? Two reasons:<br>
<br>
1. Consistency. If this proposal is accepted, all other `case` statements will be able to take a `where` clause in the exact same position.<br>
<br>
2. Expressiveness. In its new position, the `where` clause is actually in the middle—not at the end—of the case condition. This makes its role much more clear: `where` in a case condition is for refining the pattern to reject things which can&#39;t quite be expressed purely as a pattern. With `where` in this position, you will not be tempted to use it for a truly unrelated condition, as you might if `where` were after the initializer.<br>
<br>
You might be able to make an analogous argument for optional bindings, turning this:<br>
<br>
        optional-binding-head → &quot;let&quot; pattern initializer<br>
<br>
Into this:<br>
<br>
        optional-binding-head → &quot;let&quot; pattern where-clause? initializer<br>
<br>
With results like:<br>
<br>
        if let x where x &gt; 5 = optionalX { … }<br>
<br>
I&#39;m less convinced this is a good idea; there&#39;s no optional binding anywhere else in the language to be consistent with, the uses of a `where` clause are limited since an optional binding only captures one value anyway, and I don&#39;t think it makes much sense to complicate such a simple syntax.<br>
<div class="HOEnZb"><div class="h5"><br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div></div>