Hi David, I just shared a draft proposal to introduce guarded closures last week: 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>. I think you would find it very interesting.
I considered including a new capture list specifier `guard` in this proposal but decided against it. Guarded behavior requires prefixing the contents of the closure with a guard clause that returns immediately if the guard is tripped. This is a property of the closure as a whole, not of an individual capture. For that reason, I decided that allowing a `guard` specifier for an individual capture would be inappropriate. Instead, a guarded closure has a guarded by default capture behavior which can be overridden with `weak`, `unowned` or `strong` in the capture list. The thread on this proposal was relatively brief. I plan to open a PR soon after making a few minor modifications. Matthew > On Feb 22, 2017, at 2:48 PM, David Hedbor via swift-evolution > <[email protected]> wrote: > > Hello, > > (apologies if this got sent twice - gmail and Apple mail seems to confused as > to what account the first mail was sent from) > > I’m new to this mailing list, but have read some archived messages, and felt > that this would be a reasonable subject to discuss. It’s somewhat related to > the recent posts about @selfsafae/@guarded but distinctly different > regardless. > > > Problem: > > It’s often desirable not to capture self in closures, but the syntax for > doing so adds significant boilerplate code for [weak self] or us unsafe when > used with [unowned self]. Typically you’d do something like this: > > { [weak self] in self?.execute() } > > This is simple enough but often doesn’t work: > > { [weak self] in self?.boolean = self?.calculateBoolean() ] > > This fails because boolean is not an optional. This in turn leads to code > like this: > > { [weak self] in > guard let strongSelf = self else { return } > strongSelf.boolean = self.calculateBoolean() } > > And this is the boilerplate code. My suggestion is to add a syntax that works > the same as the third syntax, yet doesn’t require the boilerplate code. > > > Solution: > > Instead of using unowned or weak, let’s use guard/guarded syntax: > > > { [guard self] in > self.isExecuted = self.onlyIfWeakSelfWasCaptured() > } > > In essence, guarded self is equivalent to a weak self, that’s captured when > the closure is executed. If it was already released at that point, the > closure is simply not executed. It’s equivalent to: > > { [weak self] in > guard let strongSelf = self else { return } > strongSelf.isExecuted = strongSelf.onlyIfWeakSelfWasCaptured() > } > > Except with a lot less boilerplate code, while not losing any clarify in what > it does. > > Impact / compatibility: > > This is simply additive syntax, and wouldn’t affect any existing code. > _______________________________________________ > 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
