<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 28, 2016, at 4:42 PM, Jay Abbott 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=""><div dir="ltr" class=""><div class="">It could potentially be a breaking change if the default for @escaping closures were made to be weak-capturing.<br class=""></div></div></div></blockquote><div><br class=""></div><div>Ok, but source breaking changes need extreme justification. &nbsp;A primary goal of Swift 3 was to provide source compatibility going forward.</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Since the weak-capturing pattern is only really desirable for @escaping closures, and (I think) it would be the usual preference, could @escaping also imply weak-capturing for all references (not just self)? Then there would be another syntax for strong-capturing-escaping closures. Non-escaping closures could a) strongly capture references; or b) existing strong references stay strong and weak ones stay weak, meaning no ref-counts need to change at all when passing them.<br class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, 29 Sep 2016 at 00:06 Paul Jack via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">So previously there were a few threads on the "strong self/weak self<br class="">
dance" but they didn't seem to get anywhere. For instance:<br class="">
<br class="">
<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160201/008713.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160201/008713.html</a><br class="">
<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010759.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160215/010759.html</a><br class="">
<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009972.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009972.html</a><br class="">
<br class="">
...and possibly others.<br class="">
<br class="">
I'd like to propose something even easier (and more specific) than all<br class="">
of the above discussions. Specifically, I'd like to introduce a new<br class="">
automagic closure variable, $self, whose presence in a closure would<br class="">
cause that closure to weakly capture self in a safe manner.<br class="">
<br class="">
As a concrete example, let's imagine a UIViewController for a login<br class="">
form. Under this proposal, the following code:<br class="">
<br class="">
func viewDidLoad() {<br class="">
&nbsp; &nbsp; self.loginForm.onSubmit = {<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;let f = $self.loginForm<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$self.startLoginRequest(email:f.email.text, pwd:f.pwd.text)<br class="">
&nbsp; &nbsp; }<br class="">
}<br class="">
<br class="">
...would be treated by the compiler as equivalent to:<br class="">
<br class="">
func viewDidLoad() {<br class="">
&nbsp; &nbsp; self.loginForm.onSubmit = {<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[weak self] in<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if let selfie = self {<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;let f = selfie.loginForm<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;selfie.startLoginRequest(email:f.email.text,<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pwd:f.pwd.text)<br class="">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br class="">
&nbsp; &nbsp; }<br class="">
}<br class="">
<br class="">
Note the "if let" there: If self no longer exists, the closure does not<br class="">
execute at all, but if self does exist, then it exists for the entirety<br class="">
of the execution of the closure (ie, self won't vanish as a side-effect<br class="">
of some statement in the closure.) I think these semantics obey the<br class="">
principle of least surprise; $self can be treated by the developer as a<br class="">
strong reference.<br class="">
<br class="">
However, that does mean that $self can only be used in a closure that's<br class="">
(a) Void or (b) Optional. In the latter case, returning nil when self<br class="">
doesn't exist seems like reasonable/expected behavior.<br class="">
<br class="">
It would be a compile-time error to use both $self and normal self in<br class="">
the same closure.<br class="">
<br class="">
I'd like to keep this simple, meaning $self always does the above and<br class="">
nothing else. So, if you need an unowned self, you still need the<br class="">
original syntax; if your closure needs a non-Optional return type, you<br class="">
still need the original syntax; etc.<br class="">
<br class="">
Thoughts?<br class="">
<br class="">
-Paul<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" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</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>