<div dir="ltr">I like the idea in principle.<div><br></div><div>However, right now you can write something like:</div><div><br></div><div>if let a = optionalA, frob = fooBarBaz() { ... }</div><div><br></div><div>It&#39;s clear that both clauses are optional binding clauses.</div><div><br></div><div>With this change, it&#39;s not clear anymore whether the second clause is an optional binding clause, or a logic test erroneously using &#39;=&#39; instead of &#39;==&#39;.</div><div><br></div><div>To be fair, though, since assignment in Swift doesn&#39;t return the new value as it does in C, there is far less room for disastrous bugs caused by this sort of mistake.</div><div><br></div><div>Austin</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 20, 2016 at 10:07 AM, Erica Sadun 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"><div style="word-wrap:break-word"><div><b>Earlier on Swift Evolution:</b></div><div><br></div><div>Me: &quot;<i>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?</i>&quot;</div><div><br></div><div>Joe Groff: &quot;<i>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. </i><i>There&#39;s no technical reason we couldn&#39;t accept either &#39;where&#39; or &#39;,&#39; consistently.&quot;</i></div><div><br></div><div><font face="Menlo"><span style="white-space:pre-wrap">        </span>guard x == 0,</font></div><div><font face="Menlo"><span style="white-space:pre-wrap">        </span>  let y = optional where</font></div><div><font face="Menlo"><span style="white-space:pre-wrap">        </span>  z == 2 {</font></div><div><font face="Menlo"><span style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div><b>Pitch: </b></div><div><br></div><div>I&#39;d like to update Swift&#39;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&#39;s a real-world bit of code I was helping someone with a few evenings ago. It&#39;s attempting to navigate through some JSON, using optional conditions with where clauses.</div><div><br></div><div><div><font face="Menlo">guard</font></div><div><font face="Menlo">    let fileContents = fileContents,</font></div><div><font face="Menlo">    let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: []) as? NSDictionary,</font></div><div><font face="Menlo">    let featuresArray = jsonDict[&quot;features&quot;] as? NSArray <b>where </b></font><b><font face="Menlo">featuresArray.count &gt; 0,</font></b></div><div><font face="Menlo">    let featuresDict = featuresArray[0] as? NSDictionary,</font></div><div><font face="Menlo">    let coordinatesArray = featuresDict[&quot;geometry&quot;] <b>where </b></font><b><font face="Menlo">coordinatesArray.count &gt; 0,</font></b></div><div><font face="Menlo">    let coordinateArray = coordinatesArray[0] as? NSArray <b>where </b></font><b style="font-family:Menlo">coordinateArray.count &gt; 3</b></div><div><font face="Menlo">    else { fatalError(&quot;Reason&quot;) }</font></div></div><div><br></div><div>Each `where` test is a separate test. While there <i>are</i> semantic ties between the conditional binding and the count tests, there <i>doesn&#39;t have to be</i>. Under Swift&#39;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&#39;s an underlying semantic link between the two.</div><div><br></div><div>By removing this requirement and allowing interchangeability between `where` and `,`, you&#39;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&#39;s what this example looks like after excluding `where`:</div><div><br></div><div><span style="font-family:Menlo">guard</span></div><div><div><span style="font-family:Menlo">    let fileContents = fileContents,</span></div><div><span style="font-family:Menlo">    let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: []) as? NSDictionary,</span></div><div><span style="font-family:Menlo">    let featuresArray = jsonDict[&quot;features&quot;] as? NSArray,</span></div><div><b><font face="Menlo">    featuresArray.count &gt; 0,</font></b></div><div><span style="font-family:Menlo">    let featuresDict = featuresArray.firstObject as? NSDictionary,</span></div><div><span style="font-family:Menlo">    let coordinatesArray = featuresDict[&quot;geometry&quot;],</span></div><div><b><font face="Menlo">    coordinatesArray.count &gt; 0,</font></b></div><div><span style="font-family:Menlo">    let coordinateArray = coordinatesArray.firstObject as? NSArray,</span></div><div><span style="font-family:Menlo">    </span><b style="font-family:Menlo">coordinateArray.count &gt; 3</b></div><div><span style="font-family:Menlo">    else { fatalError(&quot;Reason&quot;) }</span></div></div><div><br></div><div>The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.</div><div><br></div><div><div><font face="Menlo">guard</font></div><div><font face="Menlo">    minimumShapeCount &gt; 4,</font></div><div><font face="Menlo">    let shapes = decompose(map, minimum: minimumShapeCount),</font></div><div><font face="Menlo">    availableArea &gt; minimumArea,</font></div><div><font face="Menlo">    let map = placeShapes(shapes, availableArea) else {</font></div><div><font face="Menlo">        fatalError()</font></div><div><font face="Menlo">}</font></div></div><div><br></div><div>would be allowed compared to current Swift which mandates where between the second and third tests:</div><div><br></div><div><div><font face="Menlo">    let shapes = decompose(map, minimum: minimumShapeCount) where </font><span style="font-family:Menlo">availableArea &gt; minimumArea,</span></div></div><div><br></div><div>In my vision, Swift would continue to allow where clauses and expand to allow disjoint Boolean entries.</div><div><br></div><div>Thoughts?</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-- E </div><div><br></div></font></span></div><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>
<br></blockquote></div><br></div>