I don't think it's a good idea to make the `weak`-ness of the closure part of 
the type system.
The current approach to `weak/unowned` is that it's a storage class that 
applies to the variable, not the value.
This makes sense because you don't *use* a weak reference, you only *store* it 
weakly.
I think this behavior has to stay the same with the addition of closures (being 
the other reference type along classes) would be eligible for storing by 
`weak/unowned` reference.

> On Jun 10, 2017, at 10:39 PM, Adrian Zubarev via swift-evolution 
> <[email protected]> wrote:
> 
> Hi Matthew,
> 
> Thank you for the hint. Indeed, at first glance your proposal is very similar 
> to my thinking. I’ll try to dive deeper into your proposal and find out more 
> about the discussion behind it when I get some more time for that.
> 
> We could collaborate on a revision for Swift 5 if you would like to, but we 
> wouldn’t need to rush now, because there is plenty of time for that. 
> 
> Personally I would love to avoid some kind of a prefix like ? if possible.
> 
> Brainstorming:
> 
> let c1 = weak someObject.method convert it to a weak closure.
> 
> let c2: weak (CLOSURETYPE)? = someObject.method Let the compiler do the job 
> for us.
> 
> The latter would be great for APIs to avoid the prefix.
> 
> .subscribe(onNext: self.bar) weak is inferred and can be omitted 
> 
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 10. Juni 2017 um 21:09:28, Matthew Johnson ([email protected] 
> <mailto:[email protected]>) schrieb:
> 
>> Hi Adrian, this is pretty similar to the Guarded Closures proposal I drafted 
>> in February.  This proposal needs a revision incorporating discussion 
>> feedback and some new ideas.  If you’re interested, here’s a link to the 
>> original discussion thread: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170213/032478.html
>>  
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170213/032478.html>.
>> 
>>> On Jun 10, 2017, at 12:29 PM, Adrian Zubarev via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Hello Evolution,
>>> 
>>> I’d like to pitch a new idea and see where it would go. Recently I tapped 
>>> into a small trap and just now realized that even that non-escaping should 
>>> have been the default for closures (SE–0103) there is an exception for 
>>> that. Apparently generics don’t follow that rule and a closure like 
>>> 
>>> Optional<() -> Void> or simply (() -> Void)?
>>> 
>>> is still escaping by default. But that was the half of the story yet. As we 
>>> all know and “love” reference lists inside closures, methods don’t have any 
>>> and we have to wrap method calls into a weak referenced closure 
>>> 
>>> { [weak self] in self.foo() }
>>> 
>>> to avoid strong reference cycles. Maybe you already guess it, I 
>>> accidentally didn’t and tapped into the land of strong reference cycles yet 
>>> again on my journey.
>>> 
>>> I’d like to pitch a new way, more like a new type behavior, for closures on 
>>> how they could be used differently in order to avoid strong reference 
>>> cycles but also providing the ability to use methods without any need to 
>>> wrap them.
>>> 
>>> Here is a simple code snippet using RxSwift, which will recreate my issue:
>>> 
>>> import RxSwift
>>> 
>>> let test = PublishSubject<Void>()
>>> 
>>> class A {
>>> 
>>>     let disposeBag = DisposeBag()
>>> 
>>>     func foo() {
>>>         test.asObservable()
>>>             .subscribe(onNext: self.bar) // The issue is here
>>>             .disposed(by: self.disposeBag)
>>>     }
>>> 
>>>     func bar() { print("works") }
>>> }
>>> 
>>> let a = A()
>>> a.foo()
>>> 
>>> test.onNext(()) // Testing if it works
>>> test.onCompleted() // Some RxSwift stuff
>>> In this case by passing directly the method self.bar we’re capturing self, 
>>> which in this situation isn’t our intention at all. To avoid this issue we 
>>> can simply wrap the method call into closure:
>>> 
>>> .subscribe(onNext: { [unowned self] in self.bar() })
>>> 
>>> (It’s safe to make it unowned because the dispose bag is a member of self.)
>>> 
>>> What if we had the ability for weak or unowned closures? By that I don’t 
>>> mean weak/unowned references to the closures themselves, because they are 
>>> also reference types, but an invalidation behavior for the whole closure 
>>> based on the _captured_ references. For instance:
>>> 
>>> let closure1: weak (() -> Void)? = { self.doWhatever() }
>>> 
>>> let closure2: weak (() -> Void)? = self.doWhatever
>>> 
>>> If one would now try to call the closure, first it will check if all the 
>>> captured objects are still available or not, if not the whole closure in 
>>> this case will simply become nil and won’t execute. In case of unowned 
>>> closures it will trap. Furthermore it will support the general meaning of 
>>> weak/unowned and will not increase the reference counter for *captured 
>>> objects*.
>>> 
>>> As you have already noticed, in this case the convention is slightly 
>>> different because we must carry the behavior directly with the type.
>>> 
>>> func subscribe(onNext: weak ((Swift.E) -> Void)?)
>>> 
>>> If the way of my thinking is correct this idea _could maybe_ fade out the 
>>> very common [weak self] in guard let strongSelf = self … pattern. 
>>> 
>>> I personally cannot tell all the technical difficulties this idea might 
>>> have, but that’s what the evolution list is for, to collaboratively flesh 
>>> out the ideas if they are worth it.
>>> 
>>> If something like this could be possible it’s probably worth noting that we 
>>> might also be able to introduce something like @autoclosure(weak/unowned) 
>>> to Swift for consistency.
>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
> 
> 
> _______________________________________________
> 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