<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 Jun 8, 2016, at 22:19, Charlie Monroe via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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">On Jun 9, 2016, at 5:51 AM, Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</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;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 8, 2016, at 9:36 PM, Brent Royal-Gordon <<a href="mailto:brent@architechies.com" class="">brent@architechies.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">Upon accepting SE-0099, the core team is removing `where` clauses from condition clauses, writing "the 'where' keyword can be retired from its purpose as a boolean condition introducer."<span class="Apple-converted-space"> </span><br class=""><br class="">Inspiried by Xiaodi Wu, I now propose removing `where` clauses from `for in` loops, where they are better expressed (and read) as guard conditions.<span class="Apple-converted-space"> </span><br class=""></blockquote><br class="">Do you propose to remove `for case` as well? That can equally be handled by a `guard case` in the loop body.<br class=""><br class="">Alternate proposal: Move `where` clauses to be adjacent to the pattern—rather than the sequence expression—in a `for` loop, just as they are in these other syntaxes.<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>for n where n.isOdd in 1...1_000 { … }<br class=""><br class="">This makes them more consistent with the syntax in `switch` cases and `catch` statements, while also IMHO clarifying the role of the `where` clause as a filter on the elements seen by the loop.<br class=""></div></div></blockquote></div><br class=""><div class="">I saw your post on that *after* I finished sending this. Moving `where` next to the pattern, like you'd find in `catch` and switch `case`, the code would look like this:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">for i where i % 2 == 0 in sequence {</font></div><div class=""><font face="Menlo" class=""> // do stuff</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><br class=""></div><div class="">I agree that's really clever and an improvement but after coming up with all the points about wrong expectations about termination vs filtering, the better use of guard, and fetishes about vertical compactness, I think (call it +0.6) I'm going to stick to my guns on this one - and for `for case` too. I've been wuxxed.</div><div class=""><br class=""></div><div class="">* New users might expect the sequence to terminate as soon as i % 2 is 1, rather than the correct interpretation which is "this is a filtering operation"</div><div class="">* The code can be expressed less ambiguously as </div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">for i in sequence.filter({ return i % 2 == 0 }) {</font></div><div class=""><font face="Menlo" class=""> // do stuff</font></div><div class=""><font face="Menlo" class="">}</font></div></div></div></blockquote><div class=""><br class=""></div>It's important to keep in mind that .filter without using .lazy copies the array. So you need to keep using sequence.lazy.filter({ return i %2 == 0 }), unless you're OK with giving up some performance, which a) adds boilerplate, b) not many people will remember to do.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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="">I've taken the time to run a test, going through milion numbers (several times) using:</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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: 9px; line-height: normal; font-family: Menlo;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">arr</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>{ </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">if</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i %<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">2</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">0</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>{ </span><span class="" style="color: rgb(187, 44, 162);">continue </span>} }</div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: 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: 9px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">arr</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">where</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i %<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">2</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">0 </span>{ }</div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">arr</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(61, 29, 129);">filter</span><span class="" style="font-variant-ligatures: no-common-ligatures;">({ $0 %<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">2</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">0</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>})</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);"> </span>{ }</div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">for</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>i<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">in</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">arr</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">lazy</span><span class="" style="font-variant-ligatures: no-common-ligatures;">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(61, 29, 129);">filter</span><span class="" style="font-variant-ligatures: no-common-ligatures;">({ $0 %<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">2</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);">0</span><span class="" style="font-variant-ligatures: no-common-ligatures;"><span class="Apple-converted-space"> </span>})</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);"> </span>{ }</div><div class=""><span class="" style="font-variant-ligatures: no-common-ligatures;"><br class=""></span></div><div class=""><div style="font-family: Helvetica; font-size: 10px;" class="">Results:</div></div><div style="font-family: Helvetica; font-size: 10px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 10px;" class="">- plain for loop with if-continue: 27.19 seconds (+1.76%)</div><div style="font-family: Helvetica; font-size: 10px;" class="">- with where: 26.72 seconds (+0.00%)</div><div style="font-family: Helvetica; font-size: 10px;" class="">- .filter: 44.73 seconds (+67.40%)</div><div style="font-family: Helvetica; font-size: 10px;" class="">- .lazy.filter: 31.66 seconds (+18.48%)</div><div style="font-family: Helvetica; font-size: 10px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 10px;" class="">Yes, 100 milion numbers is an extreme, but it demonstrates that any of the suggested expressions will be slower, mainly if the caller doesn't use .lazy (67% !!!). The only comparable solution is adding additional lines of code into the body of the for loop by adding an if statement.</div></div></div></div></blockquote><br class=""></div><div>Just to double-check, was this with optimizations on? Because -Onone numbers aren’t nearly as motivating, but I would expect -O to remove the loop entirely in the simple case.</div><div><br class=""></div><div>Jordan</div><br class=""></body></html>