<div dir="ltr">I think this is indeed an (anti-)feature of C-style loop.<div><br></div><div>`for var i = 0; i < 5; i += 1` is supposed to actually create a variable i; in particular you can change this variable yourself or pass the reference to it, so the implementation must work as follows:</div><div><br></div><div>var i = 0;</div><div>while( ...</div><div><br></div><div>Naturally, the closures are able to capture and modify i as well.</div><div><br></div><div>Or, in other words, by the definition of what C-style loop is, `for let i = 0; i < 5; i += 1` is impossible.</div><div><br></div><div>This magic behavior is in fact the best argument for the removal of C-style loop, imho.<br></div><div><br><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 6, 2015 at 10:14 PM, Erica Sadun via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>That is very odd indeed.</div><div><br></div><div>If you add explicit capture, the issue goes away:</div><div><br></div><div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">var</span> handlers: [() -> <span style="color:#703daa">Void</span>] = []</div><span class=""><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;min-height:21px"><br></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">for</span> i <span style="color:#bb2ca2">in</span> <span style="color:#272ad8">0</span>..<<span style="color:#272ad8">5</span> {</div></span><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"> <span style="color:#4f8187">handlers</span>.<span style="color:#3d1d81">append</span> {[i] <span style="color:#bb2ca2">in</span> <span style="color:#3d1d81">print</span>(i, terminator:<span style="color:#d12f1b">","</span>) }</div><span class=""><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;min-height:21px"><br></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">for</span> handler <span style="color:#bb2ca2">in</span> <span style="color:#4f8187">handlers</span> {</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"> handler() <span style="color:#008400">// "0 1 2 3 4"</span></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;min-height:21px"><br></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)">handlers<span style="color:#000000"> = []</span></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;min-height:21px"><br></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">for</span> <span style="color:#bb2ca2">var</span> i = <span style="color:#272ad8">0</span>; i < <span style="color:#272ad8">5</span>; i += <span style="color:#272ad8">1</span> {</div></span><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"> <span style="color:#4f8187">handlers</span>.<span style="color:#3d1d81">append</span> {[i] <span style="color:#bb2ca2">in</span> <span style="color:#3d1d81">print</span>(i, terminator:<span style="color:#d12f1b">","</span>) }</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;min-height:21px"><br></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;color:rgb(61,29,129)">print<span style="color:#000000">(</span><span style="color:#d12f1b">""</span><span style="color:#000000">)</span></div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">for</span> handler <span style="color:#bb2ca2">in</span> <span style="color:#4f8187">handlers</span> {</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:#000000"> handler() </span>// was "5 5 5 5 5", now 1, 2, 3, 4, 5</div><div style="margin:0px;font-size:18px;line-height:normal;font-family:Menlo">}</div></div><div><br></div><div>It really seems like a bug to me rather than a feature of the for-loop</div><div><br></div><div>-- Erica</div><div><br></div><br><div><div></div></div><blockquote type="cite"><div><div><div class="h5"><div>On Dec 6, 2015, at 12:03 PM, Kelly Gerber via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br></div></div><div><div><div class="h5"><div style="word-wrap:break-word">I think that the C-style <i>for</i> loop should be removed from Swift. The scope rules for this <i>for</i> loop are wrong. Every loop sees the same scope. This is a source of bugs if you export the loop variable name outside the scope of the <i>for</i> statement, for example in a closure. The following code illustrates the problem:<div><br></div><div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">var</span> handlers: [() -> ()] = []</div><div style="margin:0px;line-height:normal;font-family:Menlo;min-height:16px"><br></div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">for</span> i <span style="color:rgb(187,44,162)">in</span> <span style="color:rgb(39,42,216)">0</span>..<<span style="color:rgb(39,42,216)">5</span> {</div><div style="margin:0px;line-height:normal;font-family:Menlo"> <span style="color:rgb(79,129,135)">handlers</span>.<span style="color:rgb(61,29,129)">append</span> { <span style="color:rgb(61,29,129)">print</span>(i) }</div><div style="margin:0px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;line-height:normal;font-family:Menlo;min-height:16px"><br></div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">for</span> handler <span style="color:rgb(187,44,162)">in</span> <span style="color:rgb(79,129,135)">handlers</span> {</div><div style="margin:0px;line-height:normal;font-family:Menlo"> handler() <span style="color:rgb(0,132,0)">// "0 1 2 3 4"</span></div><div style="margin:0px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;line-height:normal;font-family:Menlo;min-height:16px"><br></div><div style="margin:0px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)">handlers<span> = []</span></div><div style="margin:0px;line-height:normal;font-family:Menlo;min-height:16px"><br></div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">for</span> <span style="color:rgb(187,44,162)">var</span> i = <span style="color:rgb(39,42,216)">0</span>; i < <span style="color:rgb(39,42,216)">5</span>; i += <span style="color:rgb(39,42,216)">1</span> {</div><div style="margin:0px;line-height:normal;font-family:Menlo"> <span style="color:rgb(79,129,135)">handlers</span>.<span style="color:rgb(61,29,129)">append</span> { <span style="color:rgb(61,29,129)">print</span>(i) }</div><div style="margin:0px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;line-height:normal;font-family:Menlo;min-height:16px"><br></div><div style="margin:0px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">for</span> handler <span style="color:rgb(187,44,162)">in</span> <span style="color:rgb(79,129,135)">handlers</span> {</div><div style="margin:0px;line-height:normal;font-family:Menlo"> handler() <span style="color:rgb(0,132,0)">// "5 5 5 5 5"</span></div><div style="margin:0px;line-height:normal;font-family:Menlo">}</div></div><div style="margin:0px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;line-height:normal">The Swift <i>for-in</i> loop does the right thing naturally. The C-style <i>for</i> loop does the wrong thing naturally. Removing the C-style <i>for</i> loop from Swift will eliminate one more class of possible errors from the language.</div><img alt="" width="1" height="1" border="0" style="border-width:0px!important;margin:0px!important;padding:0px!important" src="cid:02E8910D-9234-4025-8EC2-A5809BF85FC1@hsd1.co.comcast.net"></div></div></div><span class="">_______________________________________________<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" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></span></div></div></blockquote><div><br></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1p9Jer2O6jVE9KWvo-2B9iUaEyN8slp4IizyiLwsfp54PumS-2FOKt3ulmdp8EPffou5jD0A13r7R95uRKdzpRfxiRllDsouwtthPB1BVJKGuCjarm7Ok0nwlhi80h2BI2HjIJz-2BTyBdPQUPZxP-2FwYaFzoUAF0s4-2BmtOofsTHjn8zoomC02pAMnEdo3-2FSa0eCOrGVCLZNTPkEp6wOVN5TnZsoP9pxdAUdH6CrHwnzZ1x9co-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
</div>
<br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">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>
<br></blockquote></div><br></div>