<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I agree with Jonathan; furthermore, Swift already puts aside 'principled behavior' in favor of pragmatically giving Optional special treatment in quite a few other ways, none of which have bothered people as much as 'if let'.<div class=""><br class=""></div><div class="">My question is, what's the advantage any such change is going to provide in exchange for the inevitable costs of broken code and programmer friction? Is it going to prevent or reduce a commonly-made mistake, or add expressivity to the language? Is it going to allow the compiler to generate better code? Is it necessary to lay the foundation for future features? In my opinion, a slight increase in orthogonality is not really a good enough justification.<br class=""><div class=""><br class=""></div><div class="">Austin<br class=""><div class=""><div class=""><br class=""><div class=""><div class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 3, 2016, at 8:03 PM, Jonathan Tang via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">FWIW, I don't see any problems with the current "if let x = ... " syntax or behavior. I view it as a mainstream language finally implementing anaphoric-if (as described in Paul Graham's _On Lisp_), and the unwrapping seems like a natural consequence of the semantics, because what else *could* it do? The if-statement needs to test on something; it seems natural to me that the if tests for optional == nil, and then the let binds the payload of the optional if it matches.<div class=""><br class=""></div><div class="">I wouldn't rule out there being something better, but I'm -1 on all the proposals I've seen so far to change it.</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Feb 3, 2016 at 7:49 PM, Taras Zakharko 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="">I already suggested this in the bind thread but I guess it was either not interesting or people missed it, so here it goes again :)<div class=""><br class=""></div><div class="">What about changing the syntax of optional binding such that the optional unwrapping becomes explicit? I.e. instead of </div><div class=""><br class=""></div><div class=""> if let x = some_optional { }</div><div class=""><br class=""></div><div class="">one writes</div><div class=""><br class=""></div><div class=""> if let x = some_optional! { }</div><div class=""><br class=""></div><div class="">Essentially, the point of this suggestion is that the runtime error generated by unwrapping an empty Optional is instead treated as condition failure in a conditional statement. While there is some typing overhead over the current syntax, I see a number of potential benefits of this approach:</div><div class=""><br class=""></div><div class=""> 1. It is in line with the current semantics and syntax of optional unwrapping (does not introduce any new syntagm)</div><div class=""> 2. It makes the unwrapping operation explicit (thus addressing the basic criticism from the bind discussion)</div><div class=""> 3. It frees variable declaration of the contextual polisemy (i.e. let and var have the same semantics as nowhere else, there is no ‘unwrapping’ magic)</div><div class=""> 4. The change is minimal compare to what we have now and can be easily ported automatically</div><div class=""><br class=""></div><div class="">Potential issues:</div><div class=""><br class=""></div><div class=""> 1. One character typing overhead — but I dot think that should matter. I always had the impression that Swift favours clarity over compactness (which is a good thing IMO)</div><div class=""> 2. it allows syntactic ambiguity with optional chaining. E.g. if let x = a.b?.c! { } and if let x = a.b!.c would have the same meaning. Then again, this ambiguity already exits in the language to begin with. </div><div class=""><br class=""></div><div class="">— Taras</div><div class=""><div class="h5"><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 04 Feb 2016, at 01:25, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class=""><br class="">On Feb 3, 2016, at 3:47 PM, Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div style="word-wrap:break-word" class=""><div class="">Data point (which Chris brought up already, I think?): We tried this* and got a<span class=""> </span><i class="">lot</i> of negative feedback. Optionals are unwrapped too often for people to be comfortable writing "if let name? = optionalCondition”.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, I even implemented this and it was in the compiler for awhile, then later ripped it back out. You can find the history in git. I would guess that this all happened in ~March 2015.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">It may be more uniform and even more pedantically correct, but our users hated it.</div><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class="">* The actual thing we tried only allowed patterns that began with 'let', but that's close enough.</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 3, 2016, at 15:36, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class=""><div class=""><div class="">This is a continuation of and alternative proposal to "The bind thread", which seems to have petered out without consensus.<br class=""><br class="">Currently there are three forms of `if` statement (and `guard` and `while`, but for simplicity I'll just say `if` throughout this discussion):<br class=""><br class=""><span style="white-space:pre-wrap" class="">        </span>if booleanCondition<br class=""><span style="white-space:pre-wrap" class="">        </span>if let name = optionalCondition<br class=""><span style="white-space:pre-wrap" class="">        </span>if case pattern = expression<br class=""><br class="">The boolean condition form is fine, but there are flaws in the other two. `if let` is unprincipled and doesn't really say what it does; `if case` is bulky and rarely used.*<span class=""> </span><br class=""><br class="">One very interesting thing about `if case`, too, is that it can actually do optional unwrapping:<br class=""><br class=""><span style="white-space:pre-wrap" class="">        </span>if case let name? = optionalCondition<br class=""><br class="">This avoids the problems with `if let`—it's principled (it comes from a larger language feature) and it explicitly says it's handling optionality—but it still runs up against `if case`'s rarity and wordiness.<br class=""><br class="">So what I suggest is that we drop the `if let` form entirely and then drop the `case` keyword from `if case`. Pattern-matching conditions can still be distinguished from boolean conditions because boolean conditions can't contain an `=` operator. This, there would now only be two forms of if:<br class=""><br class=""><span style="white-space:pre-wrap" class="">        </span>if booleanCondition<br class=""><span style="white-space:pre-wrap" class="">        </span>if pattern = expression<br class=""><br class="">And the current `if let` is handled elegantly and clearly by existing pattern-matching shorthand, with only one additional character needed:<br class=""><br class=""><span style="white-space:pre-wrap" class="">        </span>if let name? = optionalCondition<br class=""><br class="">I see two complications with this.<br class=""><br class="">The first is that, naively, `if let foo = bar` would still be valid, but would have different and vacuous behavior, since the pattern cannot fail to match. The compiler should probably emit an error or at least a warning when this happens.<br class=""><br class="">The second is our other weird use of the `case` keyword, `for case`, which is now an orphan in the language. I see several ways this could be handled:<br class=""><br class="">1. Drop the `for case` functionality entirely; if you want that behavior, use a pattern-matching `if`.<br class="">2. Replace the loop variable slot in the `for` statement with a pattern. This would force you to put `let` on all simple `for` statements.<br class="">3. Try to automatically distinguish between simple variables/tuples and patterns in this slot. What could possibly go wrong?<br class="">4. Require an equals sign before the `in`, like `for let foo? = in optionalFoos`. Looks a little gross, but it's unambiguous.<br class="">5. Replace `for case` with `for if`, like `for if let foo? in optionalFoos`. This helps flag the unusual conditional behavior of this form of `for`.<br class="">6. Just keep `for case` and don't worry about the fact that it's not parallel to the other statements anymore.<br class=""><br class="">Thoughts on any of this?<br class=""><br class=""><br class=""><br class="">* `if case` also has the problem that the `=` isn't appropriate unless you happen to bind some of the data matched by the pattern, but I don't know how to address that. A prior version of this proposal suggested saying `:=` instead of `=`, with the idea that `:=` could become a general pattern-matching operator, but the people I talked over this post with hated that.<br class=""><br class="">--<span class=""> </span><br class="">Brent Royal-Gordon<br class="">Architechies<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></div></div></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>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></div></div></div></div></div></body></html>