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
