<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><br class=""><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline">On Dec 8, 2015, at 9:28 AM, Gwendal Roué <<a href="mailto:gwendal.roue@gmail.com" class="">gwendal.roue@gmail.com</a>> wrote:<br class=""><br class="">I’m really not found at all of having `let` properties captured by closures when used without explicit `self`.<br class=""><br class="">Three reasons:<br class=""><br class="">REASON 1. When `self` is not mandatory, then adding self should have no impact whatsoever.<br class=""><br class="">Why should one add a self that is not mandatory?<br class=""><br class="">1. for symmetry (1):<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>self.foo = other.foo<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let delta = self.x - other.x<br class=""><br class="">2. for symmetry (2):<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>init(a:String, index:Int) {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>self.name = name<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>self.position = index+1<span class="Apple-tab-span" style="white-space: pre;">        </span>// keep 1-based value for implementation reasons<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">3. add your own reasons to use an explicit self even when not required, and I’m sure you did.<br class=""><br class="">So generally speaking, using self when not mandatory should have no impact on the program at all.<br class=""><br class=""><br class="">REASON 2. What happens when a property starts its life as `let`, but turns `var` eventually? For example, the property eventually becomes lazy. OK now it’s is illegal to use the property without explicit `self` in closures, and you break a bunch of code. And you need to bump the major version of your package. Just because you turn a `let foo: String` into `lazy var foo: String = …`.<br class=""><br class="">That’s not good at all.<br class="">REASON 3. It’s simply not clear. Clever, terse, smart, brilliant, but not clear.<br class=""><br class="">Compare to:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// Obviously only `foo` is captured, and not self:<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let foo = self.foo<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>performClosure { foo }<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">These are good points, but re: reason 2, turning a public 'let' into a 'var' is already a non-resilient, semantics-breaking change, since you're taking back a promise you made about immutability. You should publish a public 'var' with a private setter if you want to reserve the right to publish mutability in the future.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">As for reason 3, the only noticeable difference between capturing an immutable property and capturing its container is that the container's lifetime might be shorter than it otherwise needs to be, so you save some memory, and weak references maybe null out sooner. If you were going to capture a weak reference to break a cycle anyway, the latter isn't a problem, and capturing the immutable value directly is preferable, since instead of disappearing, it will still be independently held by the closure.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">-Joe</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">My two cents.<br class="">Gwendal Roué<br class=""><br class=""><br class=""><blockquote type="cite" class="">Le 8 déc. 2015 à 18:01, Paul Cantrell via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :<br class=""><br class=""><blockquote type="cite" class="">For 'let' properties of classes, it'd be reasonable to propose having closures capture the *property* directly by default in this way instead of capturing ‘self'<br class=""></blockquote><br class="">That would be fantastic.<br class=""><br class="">I’ve also wondered whether there’s a tidy way for a closure to be tied to the lifecycle of self, so that when self goes away, the closure goes away too. That’s often the desired behavior. On a casual thinking through, though, it seems like a can of worms — and the “guard let self = self else { return }” proposal on another thread gives most of the same benefit.<br class=""><br class="">P<br class=""><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="">https://lists.swift.org/mailman/listinfo/swift-evolution</blockquote></blockquote></div></div><br class=""></body></html>