<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 22, 2017, at 4:06 PM, David Hedbor <<a href="mailto:neotron@gmail.com" class="">neotron@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">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:<div class=""><br class=""></div><div class=""> var opt: Bool?</div><div class=""> var closure = ?{</div><div class=""> if opt {} </div><div class=""> }</div><div class=""><br class=""></div><div class="">=></div><div class=""><br class=""></div><div class=""><div class=""> var opt: Bool?</div><div class=""> var closure = { </div><div class=""> guard let opt = opt else { return }</div><div class=""> if opt {} </div><div class=""> }</div></div><div class=""><br class=""></div><div class="">What are your thoughts on this?</div></div></div></blockquote><div><br class=""></div><div>This is a great question!</div><div><br class=""></div><div>In this example guarded closures make no difference at all because `Bool?` is a value type so it is not captured by reference.</div><div><br class=""></div><div>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.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">David</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Feb 22, 2017 at 1:40 PM, Matthew Johnson <span dir="ltr" class=""><<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Feb 22, 2017, at 3:36 PM, David Hedbor via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class="m_2520753025250174004Apple-interchange-newline"><div class=""><div dir="ltr" class="">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. <div class=""><br class=""></div><div class="">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. :)</div></div></div></blockquote><div class=""><br class=""></div></span>Thanks David, glad to hear it! </div><div class=""><div class="h5"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Cheers, </div><div class=""><br class=""></div><div class="">David</div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Feb 22, 2017 at 12:57 PM, Matthew Johnson <span dir="ltr" class=""><<a href="mailto:matthew@anandabits.com" target="_blank" class="">matthew@anandabits.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">Hi David,<div class=""><br class=""></div><div class="">I just shared a draft proposal to introduce guarded closures last week: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170213/032478.html" target="_blank" class="">https://lists.swift.org/<wbr class="">pipermail/swift-evolution/Week<wbr class="">-of-Mon-20170213/032478.html</a>. I think you would find it very interesting.</div><div class=""><br class=""></div><div class="">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. </div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Matthew</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="m_2520753025250174004h5"><div class="">On Feb 22, 2017, at 2:48 PM, David Hedbor via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class="m_2520753025250174004m_6478817709710489288Apple-interchange-newline"></div></div><div class=""><div class=""><div class="m_2520753025250174004h5"><div dir="ltr" class=""><span style="font-size:12.8px" class="">Hello,</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">(apologies if this got sent twice - gmail and Apple mail seems to confused as to what account the first mail was sent from)</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">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.</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">Problem:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">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:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> { [weak self] in self?.execute() }</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">This is simple enough but often doesn’t work:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">{ [weak self] in self?.boolean = self?.calculateBoolean() ]</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">This fails because boolean is not an optional. This in turn leads to code like this:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">{ [weak self] in</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> guard let strongSelf = self else { return }</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> strongSelf.boolean = self.calculateBoolean() }</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">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.</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">Solution:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">Instead of using unowned or weak, let’s use guard/guarded syntax:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">{ [guard self] in</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> self.isExecuted = self.</span><span style="font-size:12.8px" class="">onlyIfWeakSelfWasCaptured<wbr class="">()</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">}</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">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:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">{ [weak self] in</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> guard let strongSelf = self else { return }</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class=""> strongSelf.isExecuted = strongSelf.</span><span style="font-size:12.8px" class="">onlyIfWeakSelfWasCa<wbr class="">ptured()</span><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">}</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">Except with a lot less boilerplate code, while not losing any clarify in what it does.</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">Impact / compatibility:</span><br style="font-size:12.8px" class=""><br style="font-size:12.8px" class=""><span style="font-size:12.8px" class="">This is simply additive syntax, and wouldn’t affect any existing code.</span><br class=""></div></div></div>
______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailma<wbr class="">n/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div>
______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>