<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=""><div class="">To simplify my explanations, let's have these functions:</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class=""><font color="#5856d6" class="">func foo() {</font></div><div class=""><font color="#5856d6" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let bar: Int</font></div><div class=""><font color="#5856d6" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>withNoEscape { bar = 1 }</font></div><div class=""><font color="#5856d6" class="">}</font></div><div class=""><font color="#5856d6" class=""><br class=""></font></div><div class=""><font color="#5856d6" class="">func withNoEscape(@autoclosure(once) closure: () -> ()) { /* snip */ }</font></div></blockquote></div><div class=""><br class=""></div>Looking back, I do think that there should be a way to exit from `withNoEscape` without calling the closure, so yes, throwing should imply that the closure wasn't executed. If it's possible that `foo` swallowed an error from a throwing `withNoEscape`, the compiler should assume that the variables within haven't been initialized:<div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">func foo() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let bar: Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>try withNoEscape { bar = 1 }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>// bar has been initialized</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>catch {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>// bar has not been initialized</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">func foo() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let bar: Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>try? withNoEscape { bar = 1 }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// bar has not been initialized</div><div class="">}</div><div class=""><br class=""></div><div class="">func foo() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let bar: Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>try! withNoEscape { bar = 1 }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>// bar has been initialized</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">Closures that can throw are harder since normal functions are allowed to catch an error from a closure. For a @noescape(once) closure, it has been partially executed only and it would be non-trivial to determine what has been executed and what hasn't. As I see it, the best solution would be to force any code path in `withNoEscape` where it catches an exception from the closure to throw to indicate failure (even if the closure partially ran).</div><div class=""><br class=""></div><div class="">Another solution is to prevent `withNoEscape` from throwing, and prevent `@noescape(once)` closures from throwing. It's less classy, but the current places in the standard library where it would be nice to have it do not throw and I have a hunch that most cases won't need to throw either. Recovering from throwing closures does add a lot of complexity that I'm not sure the feature will pay for in the long run.<br 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 31 janv. 2016 à 12:54:27, Dany St-Amant via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><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=""><br class="Apple-interchange-newline">Le 31 janv. 2016 à 01:17, Félix Cloutier via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">I'd like to pitch this proposal to implement the feature: <a href="https://github.com/zneak/swift-evolution/blob/master/proposals/00xx-noescape-once.md" class="">https://github.com/zneak/swift-evolution/blob/master/proposals/00xx-noescape-once.md</a><div class=""><br class=""></div><div class="">Rationale for some points:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">Only one closure parameter can be marked as @noescape(once) in a function signature.</blockquote></div><div class=""><br class=""></div><div class="">The attribute doesn't specify the order of execution of the closures, so it could have unintended consequences if closure B depends on closure A but closure B is called first. Given the typical use case (the @noescape(once) closure as a trailing closure), I don't think that it's worth it to invest a lot of effort into coming up with a model to decide (and enforce) which closure has to be called first and what to do if either closure throws or something.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">it is not required to be executed on a code path that throws;</blockquote></div><div class=""><br class=""></div><div class="">It may need to be clarified into "must" or "must not", but I can't think about very good examples supporting either case right now.</div><div class=""><div class=""><div class=""><br class=""></div></div></div></div></div></blockquote><br class=""></div><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="">What is the implication of this @noescape(once) closure not being call on throws when the caller use try? variation? Looks like the compiler will have to assume that the @escape(once) is both not called and not not called (sorry for the double-negative). For the try!, i think that the compiler could assume that the @escape(none) is called, as the process would crash otherwise anyway on the throw.</div><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=""><br class=""></div><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=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">var</span><span class="Apple-converted-space"> </span>bad:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">Bool</span><span class="Apple-converted-space"> </span>=<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">true</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">enum</span><span class="Apple-converted-space"> </span>e:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">ErrorType</span><span class="Apple-converted-space"> </span>{</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">case</span><span class="Apple-converted-space"> </span>Simple</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">func</span><span class="Apple-converted-space"> </span>f(<span class="" style="color: rgb(187, 44, 162);">@noescape</span><span class="Apple-converted-space"> </span>closure: () -> ())<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">throws</span> {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">if</span><span class="Apple-converted-space"> </span>(bad) {<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">throw</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(79, 129, 135);">e</span>.<span class="" style="color: rgb(49, 89, 93);">Simple</span><span class="Apple-converted-space"> </span>}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> closure()</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style=""> <span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(187, 44, 162);">let</span><span class="" style=""><span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(79, 129, 135);">x</span><span class="" style="">:<span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(112, 61, 170);">Int</span><span class="" style=""> </span>// Not initialized</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">try</span>?<span class="Apple-converted-space"> </span><span class="" style="color: rgb(49, 89, 93);">f</span><span class="Apple-converted-space"> </span>{ x =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(39, 42, 216);">1</span><span class="Apple-converted-space"> </span>}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style=""> <span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(61, 29, 129);">print</span><span class="" style="">(x) <span class="Apple-converted-space"> </span></span>// May still be uninitialized, compiler must generate error</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><div class="" style="margin: 0px; line-height: normal;"> x =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(39, 42, 216);">2</span> // May have been initialized, compiler must generate error</div></div><div class=""><br class=""></div></div><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="">This should probably be highlighted in the proposal as an intended limitation for the typical usage.</div><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="">Another special case with try? that people may be unlikely to use, is:</div><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=""><br class=""></div><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=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">func</span><span class="Apple-converted-space"> </span>g(<span class="" style="color: rgb(187, 44, 162);">@noescape</span><span class="Apple-converted-space"> </span>closure: () -> ())<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">throws</span><span class="Apple-converted-space"> </span>-><span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">Int</span><span class="Apple-converted-space"> </span>{</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">if</span><span class="Apple-converted-space"> </span>(bad) {<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">throw</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(79, 129, 135);">e</span>.<span class="" style="color: rgb(49, 89, 93);">Simple</span><span class="Apple-converted-space"> </span>}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> closure()</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">return</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(39, 42, 216);">1</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">if</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">let</span><span class="Apple-converted-space"> </span>data =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">try</span>?<span class="Apple-converted-space"> </span><span class="" style="color: rgb(49, 89, 93);">g</span>({ x =<span class="Apple-converted-space"> </span><span class="" style="color: rgb(39, 42, 216);">1</span><span class="Apple-converted-space"> </span>}) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style=""> <span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(61, 29, 129);">print</span><span class="" style="">(x)<span class="Apple-converted-space"> </span></span>// Guaranteed to be initialized</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(61, 29, 129);"> print</span>(x) <span class="" style="color: rgb(0, 132, 0);">// May still be uninitialized, compiler must generate error</span></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><div class="" style="margin: 0px; line-height: normal;"> x = <span class="" style="color: rgb(39, 42, 216);">2</span> // May have been initialized, compiler must generate error</div></div></div><div class=""><br class=""></div></div><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="">Not sure if this case will make the implementation more complex, it is why I’m mentioning it.</div><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=""><br class=""></div><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="">Dany</div><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></body></html>