<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Tue, Dec 8, 2015, at 07:55 AM, Joe Groff via swift-evolution wrote:<br></div>
<blockquote type="cite"><div>One reason cycles are so prevalent with closures is that it's easy to capture too much, since referencing 'self.foo' always captures the entirety of 'self'. If the properties of 'self' you need are immutable, or you don't need to see their mutations, you can reduce the risk of cycles by capturing those properties explicitly, turning this:<br></div>
<div>&nbsp;</div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:40px;border-top-style:none;border-right-style:none;border-bottom-style:none;border-left-style:none;border-top-width:initial;border-right-width:initial;border-bottom-width:initial;border-left-width:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;"><div>self.setCallback { doStuffWith(self.zim, self.zang) }<br></div>
</blockquote><div>&nbsp;</div>
<div>into:<br></div>
<div>&nbsp;</div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:40px;border-top-style:none;border-right-style:none;border-bottom-style:none;border-left-style:none;border-top-width:initial;border-right-width:initial;border-bottom-width:initial;border-left-width:initial;border-top-color:initial;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;"><div>self.setCallback {[zim, zang] in doStuffWith(zim, zang) }<br></div>
<div>&nbsp;</div>
</blockquote><div>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' (and possibly allowing referencing them without 'self.', since 'self' wouldn't be involved in any cycle formed this way).<br></div>
</blockquote><div>&nbsp;</div>
<div>Interesting idea, but I'm concerned that this would be surprising and open up a different class of bug, where properties of self unexpectedly outlive self even though they were never referenced without going through self. This can be a problem if self has a deinit that does relevant work, or if the values of the properties themselves depend on self somehow. As a trivial example, a property of self might contain an unowned reference back to self, because it knows it will never outlive self, at least until this rule is introduced and causes a dispatch_async() to access the unowned reference after self has deinited.<br></div>
<div>&nbsp;</div>
<div>Personally, I'm happy with just using an explicit capture list for my properties if I don't want to capture self. Using this along with the practice of always omitting the `self.` whenever possible means the compiler yells at me if I accidentally capture self in an escaping closure (e.g. when I try and use a method/property without the `self.`), forcing me to make a decision there about whether I want to capture self or add a capture list for the property.<br></div>
<div>&nbsp;</div>
<div>Another alternative is to require an explicit capture list to capture self in an escaping closure, so you have to say `[self]` or `[weak self]`. This way you're forced to make a decision always. Potential downsides I can think of:<br></div>
<div>&nbsp;</div>
<div>1. It's verbose. Application code often has a lot of escaping closures, and most of them probably don't have capture lists, so that's a lot of capture lists to add.<br></div>
<div>2. It's still possible to accidentally capture self without realizing it by use of a local nested function that is itself captured. Of course, this is the same scenario that lets you capture self without even writing `self.` since local nested functions allow you to omit the `self.`, so it's already a known issue.<br></div>
<div>3. How does this interact with captures of self from enclosing closures? Right now, if I have `{ [weak self] in foo({ /* self is still weak here */ }) }`; does the inner closure need a capture list or not? How about if the outer capture is strong? `{ [self] in foo({ /* self is strong here */ }) }`? Of course, this rule would fix the current hazard of weakly capturing self at the wrong level, e.g. `{ foo({ [weak self] in ... }) }` where self is strongly captured in the outer closure, which seems to surprise people. Although now that I think of it, I'll probably submit a proposal to change that, so the outer closure captures self weakly if it's only capturing it at all because of a weak capture in a nested closure.<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
</body>
</html>