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

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


On Wed, Jun 8, 2016 at 11:34 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> 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.
>

Yikes: s/while/where. That's my queue to quit for the day.


>
>
>> * 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/7f213f8b/attachment.html>


More information about the swift-evolution mailing list