<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=""><div class="">I tend to agree with David here: there’s a lot more confusion inherent in a “var” parameter than “if var.”</div><div class=""><br class=""></div><div class="">P</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 24, 2016, at 10:58 AM, David Owens II via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class="">Removing var from function params, I get that. But the if-binding is unfortunate. It's literally a line of code for the sole purpose of making the compiler happy.&nbsp;</div><div class=""><br class=""></div><div class="">Working with optionals is already clumsy enough, we really don't need to make it more so.&nbsp;<br class=""><br class="">-David</div><div class=""><br class="">On Jan 23, 2016, at 5:03 AM, J. Cheyo Jimenez via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class="">if let currentRect = selection?.rect {</span></font></div><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class="">&nbsp; var expandedRect = currentRect&nbsp;</span></font></div></div><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></font></div><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class="">VS</span></font></div><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class=""><br class=""></span></font></div><div class=""><div class=""><font size="2" class=""><span style="background-color:rgba(255,255,255,0)" class="">if var expandedRec&nbsp;= selection?.rect {</span></font></div></div><div class=""><br class=""></div>If let is&nbsp;perfectly fine if&nbsp;most of the code base is with&nbsp;classes. Perhaps I can see the argument on why&nbsp;pattern matching and even&nbsp;why functions should only allow let but for guard and if binding, the uses of var are more practical and less boiler plate&nbsp;<span class=""></span>specially when dealing with mutable value types.&nbsp;<br class=""><br class="">On Saturday, January 23, 2016, Marc Knaup via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="">Scanning through our iOS project with ~600 Swift files we barely use `var` for function parameters or for if/guard statements.<div class=""><br class=""></div><div class="">I think the problems you outline should not be solved by using `var` but by making the code's intent much clearer by using distinct variable names.</div><div class=""><br class=""></div><div class="">In your example it is not clear what the purpose of the shadowed `rect` variable is. The same is true if you use `if var rect = …`:</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">var selection = getRectangularSelection()</font></div><div class=""><font face="monospace, monospace" class="">if let rect = selection?.rect {</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; var rect = rect // what is rect used for? the variable name is quite generic</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; // mutate `rect` ...</font></div><div class=""><div class=""><font face="monospace, monospace" class="">&nbsp; // probably a lot of code</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; // …</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class=""><font face="monospace, monospace" class="">&nbsp; selection.rect = rect // what rect again?</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><br class=""></div><div class="">A better solution is to name the variables differently and make their intent very clear:</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">var selection = getRectangularSelection()</font></div><div class=""><font face="monospace, monospace" class="">if let currentRect = selection?.rect {</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; var expandedRect = currentRect // intent becomes clear now</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; // expand `expandedRect` ...</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; // probably a lot of code</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; // …</font></div><div class=""><font face="monospace, monospace" class="">&nbsp;</font></div><div class=""><font face="monospace, monospace" class="">&nbsp; selection.rect = expandedRect // ah, THAT rect!</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><br class=""></div><div class="">So `if var` is really not necessary and causes more harm than good due to reduced clarity.</div><div class=""><br class=""></div><div class="">-1 for reversing the proposal from me.</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Jan 22, 2016 at 6:26 PM, David Farler via swift-evolution <span dir="ltr" class="">&lt;<a href="javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello everyone,<br class="">
<br class="">
I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the change in its entirety. After collecting feedback since Swift's open source launch, I no longer feel this is a good move and there are a few reasons why.<br class="">
<br class="">
There are two main patterns that the removal penalizes:<br class="">
<br class="">
- Get-Modify-Reassign<br class="">
- Get-Modify-Return<br class="">
<br class="">
I've found that many of the problems with this proposal stem from the uses before and after the "Modify" part, before returning or reassigning with the new value.<br class="">
<br class="">
I've seen a few common responses to the var removal. Consider a `Rectangle` struct:<br class="">
<br class="">
<br class="">
struct Rectangle {<br class="">
&nbsp;var origin: (x: Double, y: Double)<br class="">
&nbsp;var size: (width: Double, height: Double)<br class="">
}<br class="">
<br class="">
<br class="">
Even with mutable variables `origin` and `size`, this pattern would be impossible:<br class="">
<br class="">
<br class="">
var selection = getRectangularSelection()<br class="">
if var rect = selection?.rect {<br class="">
&nbsp;// Mutate `rect` ...<br class="">
&nbsp;selection.rect = rect<br class="">
}<br class="">
<br class="">
<br class="">
So, one might shadow the variable, which is not ideal:<br class="">
<br class="">
<br class="">
var selection = getRectangularSelection()<br class="">
if let rect = selection?.rect {<br class="">
&nbsp;var rect = rect // Not so great<br class="">
&nbsp;// Mutate `rect` ...<br class="">
&nbsp;selection.rect = rect<br class="">
}<br class="">
<br class="">
<br class="">
Or, you might make a transformation function on `Rect`:<br class="">
<br class="">
<br class="">
struct Rectangle {<br class="">
&nbsp;var origin: (x: Double, y: Double)<br class="">
&nbsp;var size: (width: Double, height: Double)<br class="">
&nbsp;func withOrigin(x: Double, y: Double) -&gt; Rect {<br class="">
&nbsp; &nbsp;var r = self<br class="">
&nbsp; &nbsp;r.origin = (x, y)<br class="">
&nbsp; &nbsp;return r<br class="">
&nbsp;}<br class="">
}<br class="">
<br class="">
<br class="">
This is a much better solution than shadowing but you would need one of these for any property that you want to mutate and I think you'll agree that it doesn't scale with the language we have today. This response begs for a kind of initializer that takes all of the fields of the original struct except any that you want to override:<br class="">
<br class="">
<br class="">
if let rect = selection?.rect.with(origin: newOrigin) {<br class="">
&nbsp;// ...<br class="">
}<br class="">
<br class="">
<br class="">
Straw syntax, but maybe you'll see something along these lines on swift-evolution in the future, which would provide a clear alternative to direct mutation patterns. Even then, I think having complementary patterns in the language isn't a bad thing.<br class="">
<br class="">
These problems come up with the other variable bindings but the one that ended up bothering me the most was `guard var`:<br class="">
<br class="">
<br class="">
func transform(selection: Rect?) {<br class="">
&nbsp;guard let rect = selection else { return }<br class="">
&nbsp;var _rect = rect<br class="">
&nbsp;// Mutate `_rect` ...<br class="">
}<br class="">
<br class="">
<br class="">
One of the guard statement's main purposes is to conditionally bind a value as a peer in its own scope, not an inner scope like if statements. Not having var makes the guard statement much weaker.<br class="">
<br class="">
There is certainly a bit of confusion about the nuances between value and reference semantics, who owns a value and when, how effects are propagated back to values, but I think we can attack the problem with more finesse.<br class="">
<br class="">
Value types are one of the attractive features of Swift – because of their semantics, mutating algorithms are written in a familiar style but keeping effects limited to your unique reference. I don't think we should give that up now to address confusion about semantics, out of principle, or in anticipation of new language features. I propose cancelling this change for Swift 3 and continue to allow `var` in the grammar everywhere it occurs in Swift 2.2.<br class="">
<br class="">
Regards,<br class="">
David<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');" target="_blank" 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="">
</blockquote></div><br class=""></div>
</blockquote>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></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=""></body></html>