<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Okay, and here is where the problem is (thanks Chris L)</div><div class=""><br class=""></div><div class="">`z = q` is an expression. It returns Void.</div><div class=""><br class=""></div><div class="">For example:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">let q = 5</font></div><div class=""><font face="Menlo" class="">var z = 0</font></div><div class=""><font face="Menlo" class="">let foo = z = q // foo inferred to have type `()` which may be unexpected</font></div><div class=""><br class=""></div><div class="">So if you have the following statement:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">guard let x = optional, z = q else {...}</font></div><div class=""><br class=""></div><div class="">where q is non-optional, there's issues in that `q` is not an optional and `z = q` is an expression.</div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On May 24, 2016, at 11:59 AM, Austin Zheng <<a href="mailto:austinzheng@gmail.com" class="">austinzheng@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I like the idea in principle.<div class=""><br class=""></div><div class="">However, right now you can write something like:</div><div class=""><br class=""></div><div class="">if let a = optionalA, frob = fooBarBaz() { ... }</div><div class=""><br class=""></div><div class="">It's clear that both clauses are optional binding clauses.</div><div class=""><br class=""></div><div class="">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 '=='.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Austin</div><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, May 20, 2016 at 10:07 AM, Erica Sadun via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><b class="">Earlier on Swift Evolution:</b></div><div class=""><br class=""></div><div class="">Me: "<i class="">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>"</div><div class=""><br class=""></div><div class="">Joe Groff: "<i class="">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 class="">There's no technical reason we couldn't accept either 'where' or ',' consistently."</i></div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><span style="white-space:pre-wrap" class="">        </span>guard x == 0,</font></div><div class=""><font face="Menlo" class=""><span style="white-space:pre-wrap" class="">        </span> let y = optional where</font></div><div class=""><font face="Menlo" class=""><span style="white-space:pre-wrap" class="">        </span> z == 2 {</font></div><div class=""><font face="Menlo" class=""><span style="white-space:pre-wrap" class="">        </span>}</font></div><div class=""><br class=""></div><div class=""><b class="">Pitch: </b></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">guard</font></div><div class=""><font face="Menlo" class=""> let fileContents = fileContents,</font></div><div class=""><font face="Menlo" class=""> let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: []) as? NSDictionary,</font></div><div class=""><font face="Menlo" class=""> let featuresArray = jsonDict["features"] as? NSArray <b class="">where </b></font><b class=""><font face="Menlo" class="">featuresArray.count > 0,</font></b></div><div class=""><font face="Menlo" class=""> let featuresDict = featuresArray[0] as? NSDictionary,</font></div><div class=""><font face="Menlo" class=""> let coordinatesArray = featuresDict["geometry"] <b class="">where </b></font><b class=""><font face="Menlo" class="">coordinatesArray.count > 0,</font></b></div><div class=""><font face="Menlo" class=""> let coordinateArray = coordinatesArray[0] as? NSArray <b class="">where </b></font><b style="font-family:Menlo" class="">coordinateArray.count > 3</b></div><div class=""><font face="Menlo" class=""> else { fatalError("Reason") }</font></div></div><div class=""><br class=""></div><div class="">Each `where` test is a separate test. While there <i class="">are</i> semantic ties between the conditional binding and the count tests, there <i class="">doesn't have to be</i>. 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.</div><div class=""><br class=""></div><div class="">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`:</div><div class=""><br class=""></div><div class=""><span style="font-family:Menlo" class="">guard</span></div><div class=""><div class=""><span style="font-family:Menlo" class=""> let fileContents = fileContents,</span></div><div class=""><span style="font-family:Menlo" class=""> let jsonDict = try NSJSONSerialization.JSONObjectWithData(fileContents, options: []) as? NSDictionary,</span></div><div class=""><span style="font-family:Menlo" class=""> let featuresArray = jsonDict["features"] as? NSArray,</span></div><div class=""><b class=""><font face="Menlo" class=""> featuresArray.count > 0,</font></b></div><div class=""><span style="font-family:Menlo" class=""> let featuresDict = featuresArray.firstObject as? NSDictionary,</span></div><div class=""><span style="font-family:Menlo" class=""> let coordinatesArray = featuresDict["geometry"],</span></div><div class=""><b class=""><font face="Menlo" class=""> coordinatesArray.count > 0,</font></b></div><div class=""><span style="font-family:Menlo" class=""> let coordinateArray = coordinatesArray.firstObject as? NSArray,</span></div><div class=""><span style="font-family:Menlo" class=""> </span><b style="font-family:Menlo" class="">coordinateArray.count > 3</b></div><div class=""><span style="font-family:Menlo" class=""> else { fatalError("Reason") }</span></div></div><div class=""><br class=""></div><div class="">The motivation for this approach becomes more compelling when the Boolean tests are disjoint from binding or pattern matches.</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class="">guard</font></div><div class=""><font face="Menlo" class=""> minimumShapeCount > 4,</font></div><div class=""><font face="Menlo" class=""> let shapes = decompose(map, minimum: minimumShapeCount),</font></div><div class=""><font face="Menlo" class=""> availableArea > minimumArea,</font></div><div class=""><font face="Menlo" class=""> let map = placeShapes(shapes, availableArea) else {</font></div><div class=""><font face="Menlo" class=""> fatalError()</font></div><div class=""><font face="Menlo" class="">}</font></div></div><div class=""><br class=""></div><div class="">would be allowed compared to current Swift which mandates where between the second and third tests:</div><div class=""><br class=""></div><div class=""><div class=""><font face="Menlo" class=""> let shapes = decompose(map, minimum: minimumShapeCount) where </font><span style="font-family:Menlo" class="">availableArea > minimumArea,</span></div></div><div class=""><br class=""></div><div class="">In my vision, Swift would continue to allow where clauses and expand to allow disjoint Boolean entries.</div><div class=""><br class=""></div><div class="">Thoughts?</div><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class=""></div><div class="">-- E </div><div class=""><br class=""></div></font></span></div><br class="">_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>