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

Reply via email to