On Wed, Feb 22, 2017 at 3:35 PM, Matthew Johnson <[email protected]> wrote:
> > > Sent from my iPad > > On Feb 22, 2017, at 5:28 PM, David Hedbor <[email protected]> wrote: > > > > On Wed, Feb 22, 2017 at 3:09 PM, Matthew Johnson <[email protected]> > wrote: > >> >> On Feb 22, 2017, at 4:57 PM, David Hedbor <[email protected]> wrote: >> >> >> >> >> On Wed, Feb 22, 2017 at 2:23 PM, Matthew Johnson <[email protected]> >> wrote: >> >>> >>> On Feb 22, 2017, at 4:06 PM, David Hedbor <[email protected]> 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. >>> >> >> Indeed, using Bool here was a bad choice for my example. >> >> >>> >>> 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. >>> >> >> >> I.e unless otherwise overridden with a [weak opt] or similar statement, >> this ?{} syntax would also enforce non-nil status of any passed in >> reference types. >> >> This could by itself be a very useful shortcut, but should probably be >> called out explicitly in the proposal just to remove any possible confusion >> of intent. As per my original question, it's most certainly obvious how >> this would be handled. I'm also not sure if this is usually the most >> desirable outcome. >> >> I think it would be more logical as a developer if your optionals remain >> optional within the block, but with the difference that they aren't >> strongly captured, and as such might become nil by the time the block >> executes, even if they weren't at the time of creation. Removing the >> optionality might force a lot of [weak param] statements that otherwise >> wouldn't be needed. >> >> >> The intent is to make this behave exactly as if you had written it out >> manually and had guarded all captured references. I think it works when it >> changes the default. It would be confusing to add special cases for things >> that are already optional. If you don’t want guarded behavior you’ll just >> need to use the capture list as you showed. >> > > > Ok, I can buy that. Still feel like this should be explicitly called out. > It's literally equivalent to [weak X] + guard let x = x { else return } for > each and every captured reference, unless otherwise overridden in the > capture list. > > > The proposal does demonstrate this but I'll give it another look. It > sounds like it's not as clear as it could be. > > Indeed it does, but with a non-optional reference. It's entirely plausible that it's obvious to most, and that I'm overthinking it. Still doesn't hurt to add a few lines specifically addressing it I think. > > >> >> >> >> >>> >>> >>> David >>> >>> >>> On Wed, Feb 22, 2017 at 1:40 PM, Matthew Johnson <[email protected] >>> > wrote: >>> >>>> >>>> On Feb 22, 2017, at 3:36 PM, David Hedbor via swift-evolution < >>>> [email protected]> 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 < >>>> [email protected]> 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. 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 >>>> >>>> >>>> >>> >>> >> >> >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
