<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>I'm very supportive of this type of proposal.</div><div><br></div><div>I do agree with Brent though that @noescape and 'once' is somewhat orthogonal.</div><div><br></div><div>There are a lot of places where you want to be clear that the block will be called but no more than once. For example, the NSURLSession callback blocks you would expect never to be called multiple times. Completion handlers are almost always used only once. I don't think this case, which is extremely common, can be overlooked.</div><div><br></div><div>On the other hand, I suspect the majority of places you use closures with @noescape, it seems more likely you'd <i>want </i>it used multiple times, like a search, filter, find etc of multiple items in a collection or group, otherwise you'd generally just put the closured activity before or after. The only areas where I would expect to see such closures of @noescape and 'once' would be dispatch_sync, or somewhere where you want to invoke custom code in the middle of a complex operation of a method.</div><div><br></div><div>It seems to me that separating them, but allowing them to be used together, makes more sense.</div><div><br></div><div>Rod</div><div><br></div><div><br>On 30 Jan 2016, at 5:05 AM, Félix Cloutier via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8">I don't have much to add but I also think that it would be nice to have.<div class=""><div class=""><div class="">
<br class="Apple-interchange-newline"><span style="color: rgb(0, 0, 0); font-family: 'Lucida Grande'; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; display: inline !important; float: none;" class="">Félix</span>
</div>

<br class=""><div><blockquote type="cite" class=""><div class="">Le 29 janv. 2016 à 12:38:01, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">On Jan 29, 2016, at 12:23 AM, Jacob Bandes-Storch via swift-evolution &lt;</span><a href="mailto:swift-evolution@swift.org" class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">swift-evolution@swift.org</a><span style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&gt; wrote:</span><div style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">I've wanted something like this as well. I think it would be harder than it seems, because "x = 1" might need to perform initialization, or assignment, depending how it's used.<div class=""><br class=""></div><div class="">It could make sense to have something like "@noescape(executed_exactly_once)" but this might be so limited it's not worth it. And I'm not sure how it should interact with throws.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I think that something like this is implementable, and making it a modifier to @noescape is sensible.</div><div class=""><br class=""></div><div class="">The semantics we could support is that the function is guaranteed to call the closure exactly once on any path that could lead to a return or throw.</div><div class=""><br class=""></div><div class="">This approach allows you to pass the closure down the stack, and composes with error handling. &nbsp;It is obviously limited what you can do with the closure, but that is necessary to validate correctness.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><br clear="all" class=""><div class=""><div class="gmail_signature"><div dir="ltr" class=""><div class="">Jacob<br class=""></div></div></div></div><br class=""><div class="gmail_quote">On Thu, Jan 28, 2016 at 11:38 PM, Gwendal Roué<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div class="" style="word-wrap: break-word;">Hello,<div class=""><br class=""></div><div class="">I’d like to discuss the opportunity to let functions declare that a closure argument is guaranteed to have been executed when the function has returned.</div><div class=""><br class=""></div><div class="">For example:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);"><span class="" style="white-space: pre-wrap;">        </span>func</span><span class="Apple-converted-space">&nbsp;</span>f(<span class="" style="color: rgb(187, 44, 162);">@noescape</span>(<span class="" style="color: rgb(112, 61, 170);">executed</span>) closure: () -&gt; ()) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="white-space: pre-wrap;">        </span>&nbsp; &nbsp; closure()</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="white-space: pre-wrap;">        </span>}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div></div><div class="">The expected advantage is that the compiler would know that a variable set inside the closure is guaranteed to be initialized, and that it can be used after the execution of the function, as below:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);"><span class="" style="color: rgb(187, 44, 162);"><span class="" style="white-space: pre-wrap;">        </span>let</span><span class=""><span class="Apple-converted-space">&nbsp;</span>x:<span class="Apple-converted-space">&nbsp;</span></span><span class="" style="color: rgb(112, 61, 170);">Int</span><span class="">&nbsp;<span class="Apple-converted-space">&nbsp;</span></span>// Not initialized</div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="color: rgb(49, 89, 93);"><span class="" style="white-space: pre-wrap;">        </span>f</span><span class="Apple-converted-space">&nbsp;</span>{<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">x</span><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(39, 42, 216);">1</span><span class="Apple-converted-space">&nbsp;</span>}</div><div class="" style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);"><span class="" style="color: rgb(61, 29, 129);"><span class="" style="white-space: pre-wrap;">        </span>print</span><span class="">(</span><span class="" style="color: rgb(79, 129, 135);">x</span><span class="">)&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span></span>// Guaranteed to be initialized</div><div class=""><br class=""></div></div></div><div class="">Today developers have to write pessimistic code like below:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style="color: rgb(187, 44, 162);"><span class="" style="white-space: pre-wrap;">        </span>var</span><span class=""><span class="Apple-converted-space">&nbsp;</span>x:<span class="Apple-converted-space">&nbsp;</span></span><span class="" style="color: rgb(112, 61, 170);">Int</span><span class=""><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span></span><span class="" style="color: rgb(39, 42, 216);">0</span><span class=""><span class="Apple-converted-space">&nbsp;</span></span>// `var` declaration, with some irrelevant value</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(49, 89, 93);"><span class="" style="white-space: pre-wrap;">        </span>f</span><span class="Apple-converted-space">&nbsp;</span>{<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">x</span><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(39, 42, 216);">1</span><span class="Apple-converted-space">&nbsp;</span>}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);"><span class="" style="white-space: pre-wrap;">        </span>print<span class="">(</span><span class="" style="color: rgb(79, 129, 135);">x</span><span class="">)</span></div></div><div class=""><span class=""><br class=""></span></div><div class="">As for a real&nbsp;world usage, I’d like to access a database in a safe (queued) way, and fetch values out of it:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);"><span class="" style="white-space: pre-wrap;">        </span>let</span><span class="Apple-converted-space">&nbsp;</span>items: [<span class="" style="color: rgb(79, 129, 135);">Item</span>]</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);"><span class="" style="white-space: pre-wrap;">        </span>let</span><span class="Apple-converted-space">&nbsp;</span>users: [<span class="" style="color: rgb(79, 129, 135);">User</span>]</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(49, 89, 93);"><span class="" style="color: rgb(79, 129, 135);"><span class="" style="white-space: pre-wrap;">        </span>dbQueue</span><span class="">.</span>inDatabase<span class=""><span class="Apple-converted-space">&nbsp;</span>{ db<span class="Apple-converted-space">&nbsp;</span></span><span class="" style="color: rgb(187, 44, 162);">in</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="white-space: pre-wrap;">        </span>&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">items</span><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">Item</span>.all().fetchAll(db)</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="white-space: pre-wrap;">        </span>&nbsp; &nbsp;<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">users</span><span class="Apple-converted-space">&nbsp;</span>=<span class="Apple-converted-space">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">Item</span>.all().fetchAll(db)</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="white-space: pre-wrap;">        </span>}</div></div><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class=""></div><div class="">Gwendal Roué</div><div class=""><br class=""></div></font></span></div><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""><br class=""></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class="" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: LucidaGrande; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>