<div dir="ltr">I respectfully disagree with the need for bind operator, see below:<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Feb 1, 2016 at 8:18 PM, Erica Sadun via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word">Joe says "<span style="font-family:Palatino-Roman">If you all are serious about this, I think you should start a new thread about it." </span><div>I think it's worth a serious discussion just so it can be evaluated and either adopted or discarded</div><div>and dropped forever. Here goes.</div><div><br></div><div>INTRO</div><div><br><div>The <font face="Menlo">if let x = x {...}</font> and <font face="Menlo">guard let x = x else {...}</font> constructs do something with <font face="Menlo">let</font> (and <font face="Menlo">var</font>) that's </div><div>fundamentally different from <font face="Menlo">let</font> (and <font face="Menlo">var</font>) elsewhere in the language. The same keywords are used to conditionally unwrap</div><div>and bind an item, not just shadow that item's current value.</div></div></div></blockquote><div><br></div><div><span style="font-family:Menlo">let A = B</span> does exactly the same in all instances: evaluate the expression B in current scope and bind the result to a local name A, and <span style="font-family:Menlo">if let x = x</span> meaning is no different. If a person doesn't know the precise meaning of if let, with the similarity to normal let one is likely to guess at least the "name binding" part. This is a big advantage of if let syntax.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><br></div><div>Introducing a new <font face="Menlo">bind</font> keyword to indicate unwrapping and binding would disambiguate these uses.</div><div><br></div><div>DETAIL DESIGN:</div><div><br></div><div>Jacob Bandes-Storch offers two common use-cases. I prefer his "if bind foo" to my original "if bind foo = foo":</div><div><br></div><div><div><font face="Menlo"> if bind foo {</font></div><div><font face="Menlo"> // foo is non-optional in here</font></div><div><font face="Menlo"> }</font></div><div><font face="Menlo"><br></font></div></div></div></div></blockquote><div><br></div><div>Let's consider the case where foo was originally a property. Unfortunately, the syntax above is then very likely to confuse people into thinking that self.foo is non-optional inside the inner scope, which is far from guaranteed:</div><div><br></div><div><span style="font-family:Menlo">if bind foo {</span><br></div><div><span style="font-family:Menlo"> // we have created a local variable foo here</span></div><div><span style="font-family:Menlo"> // foo is non-optional</span></div><div><span style="font-family:Menlo"> // no guarantees about self.foo can be made, however</span></div><div><span style="font-family:Menlo"> // as it's value may have changed</span></div><div><span style="font-family:Menlo">}</span></div><div><br></div><div>The same applies if foo is a local variable captured by an escaped closure which may be executing concurrently with the inner block.</div><div><br></div><div>So it seems like the bind statement is most helpful only when foo is a local name and either declared with let or not captured by any escaped closure. In that case the original foo can be used directly without shadowing. </div><div><br></div><div>One sees how such a statement can be useful, but I'm not sure if the word bind is the best one for it. After all, both let and var perform name binding. Also, there were suggestions to make </div><div><div><span style="font-family:Menlo"><br></span></div><div><span style="font-family:Menlo">// foo is local and not escaping</span></div><div><span style="font-family:Menlo">if foo != nil {</span><br></div><div><span style="font-family:Menlo"> // foo is non-optional</span><br></div><div><span style="font-family:Menlo">}</span><br></div></div><div><br></div><div>simply work without any additional syntax. Perhaps one can look into that.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div><font face="Menlo"></font></div><div><font face="Menlo"> somethingAsync { [weak self] in</font></div><div><font face="Menlo"> guard bind self else { return }</font></div><div><font face="Menlo"> // ...</font></div><div><font face="Menlo"> }</font></div></div><div><br></div></div><div>JBS's approach offers my original "bind" keyword to unwrap and shadow bind, but also provides a way to </div><div>strongly bind a weak reference to self, which (presumably) would allow self semantics in the remaining</div><div>lifetime of that scope.</div><div><br></div><div>ALTERNATIVE PROPOSALS:</div><div><br></div><div>Tino Heth proposes a second use-case one with different semantics. This case, it seems to make an</div><div>alias rather than using binding for shadowing:</div><div><br></div><div><font face="Menlo">bind x = a.property.with.a.long.path<br>print x // 42<br>print(a.property.with.a.long.path == 42) => true</font></div><div><span style="font-family:Palatino-Roman"><br></span></div><div><span style="font-family:Palatino-Roman">presumably this means:</span></div><div><span style="font-family:Palatino-Roman"><br></span></div><div><font face="Menlo">x += 1</font></div><div><font face="Menlo">print(a.property.with.a.long.path) // 43</font></div><div><font face="Palatino-Roman"><br></font></div><div><font face="Palatino-Roman">DISCUSSION</font></div><div><font face="Palatino-Roman"><br></font></div><div><font face="Palatino-Roman">I'm throwing these both out there. I have nothing to really say about Tino's but I do think my and Jacob's </font></div><div><font face="Palatino-Roman">proposal has the advantages of:</font></div><div><font face="Palatino-Roman"><br></font></div><div><font face="Palatino-Roman">* Simplifying an mildly complex and potentially misleading statement </font></div><div><font face="Palatino-Roman">* Creating a deliberate and controlled rather than accidental shadowing style</font></div><div><font face="Palatino-Roman"><br></font></div><div><font face="Palatino-Roman">Have at it.</font></div><span class=""><font color="#888888"><div><font face="Palatino-Roman"><br></font></div></font></span></div></blockquote><div><br></div><div>The 'big picture argument' is that shadowing is likely to introduce more errors, so we should be discouraging it, not encouraging. In real life I find creating a local variable with a different name more natural anyway, e.g:</div><div><br></div><div><div><span style="font-family:Menlo">// </span><font face="Menlo">issuesViewController is a property</font></div><div><font face="Menlo">// we want to present it, if it can be constructed</font></div><div><span style="font-family:Menlo"><br></span></div><div><span style="font-family:Menlo">if let to_present = issuesViewController {</span><br></div><div><font face="Menlo"> presentViewController(to_present, animated: true)</font></div><div><span style="font-family:Menlo">}</span><br></div></div><div><span style="font-family:Menlo"><br></span></div><div>Ilya.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><font color="#888888"><div><font face="Palatino-Roman"></font></div><div><font face="Palatino-Roman">-- Erica</font></div><div><font face="Palatino-Roman"><br></font></div><div><font face="Palatino-Roman"><br></font></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></div>