<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="">I’m against removing “where" from “for/in”. I use it in my code and I think it aids readability quite a bit. In the example:<div class=""><br class=""></div><div class=""><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 16px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal;" class="">for x in theArray where x % 2 == 1 { print (x) }
</code></pre></div><div class="">I think it’s artificially confusing because the print is on the same line. If we break the line we see the “where” at the end of the line and it reads like the English I would use to tell someone what this loop is doing:</div><div class=""><br class=""></div><div class=""><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; margin-top: 0px; margin-bottom: 16px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class=""><div style="font-family: 'Helvetica Neue'; white-space: normal;" class=""><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; margin-top: 0px; margin-bottom: 16px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;" class=""><code style="color: rgb(51, 51, 51); font-size: 14px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal;" class="">for x in theArray where x % 2 == 1 {
</code><span style="white-space: normal; background-color: transparent; font-size: 14px;" class=""><font color="#333333" class="">... </font></span></pre></div></pre></div><div class="">To me this reads very clearly: I’m looping through some values BUT I want to skip some, now here’s what I’m going to do with these values. Using “guard” for this purpose adds unnecessary lines of code and also allows for the (common in my experience!) bug of accidentally using “break” or “return” inside the guard instead of “continue”. Also, guard / continue just doesn’t read like a filter.</div><div class=""><br class=""></div><div class="">Having the filtering/where logic (eg: what I’m _iterating_ over) separated from the body of the loop (eg: what i’m _doing_ to those objects) is one of my favorite things about Swift.</div><div class=""><br class=""></div><div class="">Yes, we could also do that with “filter” followed by “forEach”, but then it would read totally backwards and I don’t always want that. (I mean, at this point “for/in blah” could be considered syntactic sugar for "blah.forEach {}” but I still want "for/in".)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><pre style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; margin-top: 0px; margin-bottom: 16px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: rgb(51, 51, 51);" class=""><code style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 0px; margin: 0px; background-color: transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; word-wrap: normal;" class="">for x in theArray where x % 2 == 1 { print (x) }
while let x = anArray.popLast() where x % 2 == 1 { print(x) }
</code></pre></div></div><div class="">In this example case the “while” is only unclear to me because Swift has the odd thing where it does pattern matching using “let” as well as using let in a plain old assignment, and it’s hard to know which is which. I could argue that it’s also unclear why I can’t type “let x = anArray popLast where x % 2 == 1” by itself on a line and have x be an optional. (I would have liked it if we used “match” as a keyword instead of “let” when we’re doing patterns, but there you go.)</div><div class=""><br class=""></div><div class="">-Wil</div></body></html>