<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 Dec 11, 2015, at 8:27 AM, Erica Sadun via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; 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="">As for c-style-for vs while, the two are mechanically convertible.</span></div></blockquote></div><br class=""><div class="">This is provably false and has been demonstrated, but here is an example of it again:&nbsp;</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;var&nbsp;sum =&nbsp;0<br class="">&nbsp; &nbsp;&nbsp;for&nbsp;var&nbsp;i =&nbsp;10 /* expr1 */; i &gt;&nbsp;0 /* expr2 */; i -=&nbsp;1 /* expr3 */&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;i %&nbsp;2&nbsp;==&nbsp;0&nbsp;{&nbsp;continue&nbsp;} // statement<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;sum +=&nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // statement<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;print(sum)<br class=""><br class=""><br class="">&nbsp; &nbsp;&nbsp;var&nbsp;sum =&nbsp;0<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;i =&nbsp;10&nbsp;// expr1<br class="">&nbsp; &nbsp;&nbsp;while&nbsp;i &gt;&nbsp;0&nbsp;/* expr2 */&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;i %&nbsp;2&nbsp;==&nbsp;0&nbsp;{&nbsp;continue&nbsp;}&nbsp;// statement<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;sum +=&nbsp;1&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// statement<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;i -=&nbsp;1&nbsp;// expr3<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;print(sum)<br class=""></font><br class="">It’s not just a mechanical conversion; consideration for early loop-exits and continuations need to be made as well. The rote conversion for the while version above is an infinite loop. Not only that, expr1 now leaks variables into a scope that is no longer contained within the loop.&nbsp;<br class=""><br class=""><blockquote type="cite" class="">Where heavy performance is not required, for-in is more readable, maintainable, and optimizable to a sufficient extent that I do not see it as a bar to conversion.<br class=""></blockquote><div class=""><br class=""></div><div class="">This is a pure philosophical difference that I don’t think we’ll agree on. The injection of types are required to make for-in constructs work with the hope that the optimizer can clean all of this up later. This is fundamentally the same claim that C++ makes with it’s zero-cost abstraction. Mike Action has some great talks on YouTube that demonstrate many of the real-world problems he runs into.</div><div class=""><br class=""></div><div class="">Should the for ;; construct be used for all loop iteration? No, I don’t think so. But we shouldn’t make the claim that the while-loop is an equivalent form, because it’s not. Can it be used to mimic the functionality? Of course, but not in a mechanical conversion like you suggest. Care has to be taken that the statements don’t essentially branch and an artificial scope needs to be added.&nbsp;</div><div class=""><br class=""></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; if true {</span></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; var</span><span style="font-family: Menlo;" class="">&nbsp;sum =&nbsp;</span><span style="font-family: Menlo;" class="">0</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">var</span><span style="font-family: Menlo;" class="">&nbsp;i =&nbsp;</span><span style="font-family: Menlo;" class="">10</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">// expr1</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">while</span><span style="font-family: Menlo;" class="">&nbsp;i &gt;&nbsp;</span><span style="font-family: Menlo;" class="">0</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">/* expr2 */</span><span style="font-family: Menlo;" class="">&nbsp;{</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">if</span><span style="font-family: Menlo;" class="">&nbsp;i %&nbsp;</span><span style="font-family: Menlo;" class="">2</span><span style="font-family: Menlo;" class="">&nbsp;==&nbsp;</span><span style="font-family: Menlo;" class="">0</span><span style="font-family: Menlo;" class="">&nbsp;{&nbsp;</span><span style="font-family: Menlo;" class="">continue</span><span style="font-family: Menlo;" class="">&nbsp;}&nbsp;</span><span style="font-family: Menlo;" class="">// statement</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">sum +=&nbsp;</span><span style="font-family: Menlo;" class="">1</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">// statement</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">i -=&nbsp;</span><span style="font-family: Menlo;" class="">1</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">// expr3</span><br style="font-family: Menlo;" class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">}</span></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp; }</span></div><div class=""><span style="font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;</span><span style="font-family: Menlo;" class="">print</span><span style="font-family: Menlo;" class="">(sum)</span></div><div class=""><br class=""></div><div class="">And then there is this:</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">Performance is definitely a consideration; we already reverted a pull request that remove C-style fors from the standard library. I believe Andy is currently looking into where the regressions come from. stride(...) performing poorly seems like something we should fix regardless, since that's arguably the idiomatic way to write such loops and ought to perform well. I agree we should investigate ways to ensure common loops over ranges or strides perform reasonably at -Onone if we move forward with this.</div></blockquote><div class=""><br class=""></div></div>-David</div></body></html>