<div dir="ltr">Does the compiler treat a nested function differently from a closure in any meaningful way? (I suppose they might have symbols emitted in the symbol table, whereas a closure assigned to a local variable wouldn&#39;t?)<div><br></div><div>It definitely seems odd that you can write two functionally equivalent pieces of code (one with a closure, one with a nested function) and can only address the capturing semantics in one of them. Unifying these seems like a good idea.</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Oct 25, 2017 at 10:12 AM David Sweeris via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Oct 25, 2017, at 4:41 AM, David Hart via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-3640882179226238874Apple-interchange-newline"><div><div style="word-wrap:break-word">I got bit again by a sneaky memory leak concerning local functions and would like to discuss a small language change. I vaguely remember this being discussed in the past, but can’t find the thread (if anybody could point me to it, I’d appreciate it). Basically, here’s an example of the leak:<div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;color:rgb(36,41,46)"><span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">class</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">A</span> {
    <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">foo</span>() {
        <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">local</span>() {
            <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>()
        }
    
        methodWithEscapingClosure { [<span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">unowned</span> <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">self</span>] <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">_</span> <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">in</span>
            <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">self</span>.<span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>()
            <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">local</span>() <span class="m_-3640882179226238874pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"><span class="m_-3640882179226238874pl-c" style="box-sizing:border-box">//</span> this leaks because local captures self</span>
<span class="m_-3640882179226238874pl-c" style="box-sizing:border-box;color:rgb(106,115,125)"></span>        }
    }
    
    <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">bar</span>() {
    }
}</pre><div><br></div></div><div>Its sneaky because local’s capturing of self is not obvious if you’ve trained your brain to watch out for calls prefixed with self. I would suggest having the compiler force users to make self capturing explicit, the same way it does for closures:</div><div><br></div><div><pre style="box-sizing:border-box;font-family:SFMono-Regular,Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:0px;word-wrap:normal;padding:16px;overflow:auto;line-height:1.45;background-color:rgb(246,248,250);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;color:rgb(36,41,46)"><span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">class</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">A</span> {
    <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">foo</span>() {
        <span class="m_-3640882179226238874pl-k" style="box-sizing:border-box;color:rgb(215,58,73)">func</span> <span class="m_-3640882179226238874pl-en" style="box-sizing:border-box;color:rgb(111,66,193)">local</span>() {
            <span class="m_-3640882179226238874pl-c1" style="box-sizing:border-box;color:rgb(0,92,197)">bar</span>() // error: Call to method ‘bar&#39; in function ‘local&#39; requires explicit &#39;self.&#39; to make capture semantics explicit
        }
    
<span class="m_-3640882179226238874Apple-tab-span" style="white-space:pre-wrap">        </span>// ...
    }
}</pre><div><br></div></div><div>What do you think?</div></div></div></blockquote><br></div></div><div style="word-wrap:break-word"><div>Works for me</div><div><br></div><div>- Dave Sweeris</div><br></div>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>