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.

> 
>  
>> 
>>> 
>>>  
>>>> 
>>>>> 
>>>>> 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

Reply via email to