[swift-evolution] SE-0105: Removing Where Clauses from For-In Loops

Xiaodi Wu xiaodi.wu at gmail.com
Fri Jun 24 15:03:58 CDT 2016

On Fri, Jun 24, 2016 at 1:38 PM, Tony Allevato <allevato at google.com> wrote:

> On Fri, Jun 24, 2016 at 11:30 AM Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>> On Fri, Jun 24, 2016 at 6:37 AM, William Shipley <wjs at mac.com> wrote:
>>> On Jun 23, 2016, at 11:04 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>> Not a practitioner of 80-character line limits, I take it?
>>> I don’t understand why anyone wouldn’t just let Xcode do the wrapping
>>> for most cases. I’ll add newlines if I think it adds to clarity, but in
>>> general I don’t want to code like i’m still on a Wyse WY-50.
>> Of course, to each their own style--I certainly wouldn't want Swift to
>> force everyone to write lines of certain lengths. But 80-character lines is
>> a common style, and I would say that a corollary of "to each their own" is
>> that Swift's grammar should be usable and useful whether or not you adhere
>> to such style choices.
>> If the chief advantage of `where` is that it (quoting someone above)
>> allows one to "understand as much as possible about the control flow of
>> the loop from a single line of code," then we ought perhaps to question its
>> appropriateness when the majority of its benefits [by which I mean, based
>> on your examples and Sean's, more than half of the instances in which it is
>> used] cannot be realized in a very common coding style.
> IMO, we shouldn't be talking about "a single line of code" so much as "a
> single cohesive construct". What's important to me isn't the line length or
> whether the "where" part has to wrap onto another line, it's the number of
> potentially divergent constructs I have to parse mentally in order to
> determine the meaning of the loop.
> With "for-in-where", it's three:
>     for item(1) in someCollection(2) where someCondition(3)
> With the alternatives suggested using if/guard/continue/break, it's more
> than that:
>     for item(1) in someCollection(2) {
>         [if | guard...else](3) someCondition(4) {
>             [continue | break](5)
>         }
>     }
> I have to be more careful now interpreting the meaning of this loop
> because both or either of if/guard or continue/break can invert its
> meaning, where was "for-in-where" is concise and clear.

I like this way of thinking a lot, actually. Number of divergent constructs
you have to parse. Here's the thing: I think it supports removal, not
retaining. Here's why:

For every loop you encounter, to understand its meaning you *must* look for
`break` and `continue` statements, and when they're inside `if` and `guard`
you must consider how the condition is evaluated. This is a given, a sunk
cost; I see no way they can be prohibited from the language, so these are
all things you will have to look for and mentally parse in order to
understand the behavior of a loop.

Now, if you add `where`, then that is one additional divergent construct
you must understand and parse. And moreover, since you know it exists, to
be sure you really understand what's going on you'll have to check the end
of every `for...in` statement to see if it's there. And in case the line
doesn't fit on your screen, you'll have to try scrolling to see if there's
more (or read on to the next line if you've turned on line wrapping). And
you'll have to do this for *every* `for...in` loop, where the majority
don't use `where` at all!

So, I agree with you, what's important to me as well is number of divergent
constructs I have to parse. But with the removal of `where`, the number of
divergent constructs I have to think about while reading Swift loops will
decrease, not increase.

Doing .lazy.filter{...} is slightly cleaner than this, but still suffers
> from the disadvantage that it's very easy for newcomers to leave out the
> "lazy" part and accidentally write poorly performing code, and to the
> argument that "where" is considered confusing by some users, I would argue
> that it's easier to explain how it works than why "lazy" is necessary in
> this context.
>> _______________________________________________
>> 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/20160624/0c887aa6/attachment.html>

More information about the swift-evolution mailing list