> On Feb 22, 2017, at 4:06 PM, David Hedbor <neot...@gmail.com> wrote: > > One more thing I'd like to add into the discussion is handling of optional > variables. My assumption is that if I have an optional variable in the outer > scope, it would remain optional in the inner scope, but the way the draft is > worded, it might seem like it would add an implicit guard statement in that > situation. i.e: > > var opt: Bool? > var closure = ?{ > if opt {} > } > > => > > var opt: Bool? > var closure = { > guard let opt = opt else { return } > if opt {} > } > > What are your thoughts on this?
This is a great question! In this example guarded closures make no difference at all because `Bool?` is a value type so it is not captured by reference. If it was an optional reference type the guard would fire as soon as the value was `nil` which would be immediately if the value was already `nil` when the closure was created. This is the same behavior you would get today by writing it out manually. > > David > > > On Wed, Feb 22, 2017 at 1:40 PM, Matthew Johnson <matt...@anandabits.com > <mailto:matt...@anandabits.com>> wrote: > >> On Feb 22, 2017, at 3:36 PM, David Hedbor via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> I did read it, but I think I skimmed it a bit too fast. You're correct in >> that it essentially solves the same problem using a different syntax (more >> compact at that). I think when I initially read it, I parsed it as the >> method would return at any point if the objects were freed (mid-execution of >> the closure). Re-reading it, I see that the proposal is in fact identical in >> functionality to mine, just with a different syntax. >> >> Given that your proposal still allows for overriding the behavior on an >> individual basis, the same thing can be accomplished. I'll put my support >> behind your draft, rather than expending more time with mine. :) > > Thanks David, glad to hear it! > >> >> Cheers, >> >> David >> >> >> On Wed, Feb 22, 2017 at 12:57 PM, Matthew Johnson <matt...@anandabits.com >> <mailto:matt...@anandabits.com>> wrote: >> 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 >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution