[swift-evolution] [Pitch] Retiring `where` from for-in loops

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 8 23:34:34 CDT 2016


On Wed, Jun 8, 2016 at 11:17 PM, Sean Heber via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On Jun 8, 2016, at 10:51 PM, Erica Sadun via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On Jun 8, 2016, at 9:36 PM, Brent Royal-Gordon <brent at architechies.com>
> wrote:
>
> 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."
>
> Inspiried by Xiaodi Wu, I now propose removing `where` clauses from `for
> in` loops, where they are better expressed (and read) as guard conditions.
>
>
> Do you propose to remove `for case` as well? That can equally be handled
> by a `guard case` in the loop body.
>
> 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.
>
> for n where n.isOdd in 1...1_000 { … }
>
> 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.
>
>
> 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:
>
> for i where i % 2 == 0 in sequence {
>     // do stuff
> }
>
>
> This is the best version yet - the placement of 'where' makes total sense
> and I really like it there.
>
>
> 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.
>
>
Maybe it's the late hour and staring at this too much. For the moment I
think I could live with either not having `where` like Erica proposes or
having it moved like Brent proposes. Perhaps later I'll form a considered
preference.

Brent's idea is so new, yet I have to admit it does feel somehow--this is a
squishy evaluation--satisfying? One thing about it that I like over
previous proposals--that's if we're going to go down this route rather than
taking out `while` altogether--is that the word `in` seems to instinctively
encourage concision. It just feels weird to stuff too much between `for i`
and `in`, so I think people will tend to use it in a more reasonable way
(with nothing to prove this intuition at all, of course).

Then again, it should come as no surprise that I agree with Erica that
removing `while` altogether has the benefit of definitively eliminating any
kind of misinterpretation as to termination vs. filtering. That's a win.


> * 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"
> * The code can be expressed less ambiguously as
>
> for i in sequence.filter({ return i % 2 == 0 }) {
>     // do stuff
> }
>
>
> This seems to trade what was a very declarative syntax about the intent of
> some code (especially with 'where' in the middle of the statement) for one
> that injects its own specialized vocabulary into the context (knowing what
> filter does, a function call, a closure with a return keyword and a pair of
> extra braces and parenthesis!) which means, to me anyway, significant
> cognitive overhead. It will also be a lot slower without optimization
> enabled due to the intermediate array. (I've found *significant* speed ups
> switching .forEach() with for loops in debug builds, for example.)
>
>
> * The while version can be expressed as
>
> for i in sequence.prefix(while: { return $0 % 2 == 0 } ) {
>     // do stuff
> }
>
>
> And now we've gone from, again, what is likely a very simple and
> declarative style using a for/while kind of statement and turned it in to
> something that has *even more* cognitive overhead to figure out what it
> does because now I have to reason about what "prefix" means here (normally
> I only think of prefix in the context of strings) and if there's a special
> variation of it using the "while" argument that I need to also be aware
> of...
>
> Maybe it's just me, but.. I don't get it. I want to be able to quickly
> understand a piece of code's intent, not wade through fancy constructions
> for their own sake.
>
> l8r
> Sean - who might be too tired to be emailing responsibly
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160608/9de06687/attachment.html>


More information about the swift-evolution mailing list