Thanks for chiming in, Joe, and apologies for not replying promptly!

> "self.doSomething" method applications are also the only place where we 
> directly capture an object into a closure without explicit closure syntax, 
> which is where much of the surprise about memory leaks comes from.

Ohhh. So that’s interesting. Makes total sense, but from a programmer’s 
perspective I just thought of `self.doSomething` as nothing more than a 
function reference. But, if I understand correctly, it’s actually equivalent to 
`{ [self] in Foo.doSomething(self)($0) }`, correct?

> Even when strong references are desired, it's arguable that { 
> self.doSomething($0) } is still preferable, since it's more obviously 
> capturing `self`, and that the 'self.doSomething' shorthand is a misfeature.

Hm. Not having the shortcut would suck a bit, but it’s hard to argue with the 
fact that it’s much clearer you’re doing something potentially dangerous.

What about this, then: rip out the `self.doSomething` method applications, but 
have a shortcut, like the ones I proposed, that’s more explicit about the 
method capture:

#strong(self.doSomething) // <— currently just self.doSomething
#weak(self.doSomething)
#unowned(self.doSomething)

The balance of closure syntaxes is zero ;) but the Misfeature Shorthand is now 
clearer, and forming weak/unowned-self is easier and less noisy.

— Radek

> On 01 Apr 2016, at 19:35, Joe Groff <[email protected]> wrote:
> 
> As we briefly discussed on Twitter, I feel like Swift already has too much 
> closure syntax as it is. { [unowned self] self.doSomething($0) } is 
> definitely more text than self.doSomething, but it's clear what it's doing. 
> "self.doSomething" method applications are also the only place where we 
> directly capture an object into a closure without explicit closure syntax, 
> which is where much of the surprise about memory leaks comes from. Even when 
> strong references are desired, it's arguable that { self.doSomething($0) } is 
> still preferable, since it's more obviously capturing `self`, and that the 
> 'self.doSomething' shorthand is a misfeature.
> 
> -Joe
> 
>> On Apr 1, 2016, at 8:09 AM, Radosław Pietruszewski via swift-evolution 
>> <[email protected]> wrote:
>> 
>> Here’s a pattern I find myself doing quite often:
>> 
>> 1> class Child {
>> 2.     var onSomeEvent: () -> Void = { }
>> 3. }
>> 4> class Parent {
>> 5.     let child = Child()
>> 6.     init() {
>> 7.         child.onSomeEvent = doSomething
>> 8.     }
>> 9.     func doSomething() {
>> 10.     }
>> 11. }
>> 
>> I have some ownership hierarchy of classes (often controllers — view 
>> controllers — views), where I pass information from children up to parents 
>> using closures set by the parent.
>> 
>> I like this pattern because children classes don’t have to be tied to 
>> knowledge about their parents, and I don’t have to define delegate 
>> protocols. It’s very clean, and also very easy to set up.
>> 
>> The only problem is that there’s a strong danger of introducing reference 
>> cycles.
>> 
>> With class properties, you can quite easily see the potential for a 
>> reference cycle and mark references to parents with weak/unowned. And with 
>> `self` captures in closures, you’re reminded of memory management by having 
>> to be explicit about `self`. But when passing references from parents to 
>> children, there’s no way to mark the closure property as `weak` (and there’s 
>> no reminder of the danger).
>> 
>> * * *
>> 
>> Right now, every time I pass a closure down to children, I have to wrap my 
>> references like so:
>> 
>>      { [unowned self] self.doSomething($0) }
>> 
>> instead of a neat and simple function reference:
>> 
>>      doSomething
>> 
>> I think it would be useful to have a shortcut syntax for creating weak and 
>> unowned references to functions, like so:
>> 
>>      @unowned(doSomething)
>> 
>> or perhaps:
>> 
>>      #unowned(self.doSomething)
>> 
>> * * *
>> 
>> An alternative would be the ability to mark closure properties as weak or 
>> unowned. Then I could, at the *child* level, say:
>> 
>>      unowned let onSomeEvent: () -> Void
>> 
>> * * *
>> 
>> Does this make sense? What do you think?
>> 
>> — Radek
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to