> On 10 Jun 2016, at 19:10, Xiaodi Wu via swift-evolution 
> <swift-evolution@swift.org> wrote:
> So "inessential" alone is not a good sole criterion--I agree. But it is one 
> of several prongs here: `where` is not only inessential, I argue that it 
> lacks expressiveness (in that what is enabled by it can be expressed equally 
> or even more cogently with `guard`, a more general and more expressive syntax 
> overall), and it detracts from rather than helps with writing correct code, 
> because we hear attestations that its use has gone awry (and the going awry 
> happens at runtime!). So in essence, I would be content with inessential but 
> expressive solutions, but here I argue that `where` is neither essential nor 
> expressive.

You’ve argued this several times, but I think the code speaks well enough for 
itself:

        for eachValue in theValues where eachValue.isOdd { … }
        for eachValue in theValues {
                guard eachValue.isOdd else { continue }
        }

Not only is it an extra 15+ characters, it’s an extra line, so there’s a 
definite saving right away.

The key issue is people misunderstanding that where is equivalent to continue 
and not break; this may be an issue of consistency, which will go away if 
“where” is doomed to be removed from conditionals (which I believe includes 
while loops). Otherwise it seems like it’s based on a mistaken assumption that 
the for in loop wants to terminate rather than continue, but really its purpose 
is to visit as many matching elements of a sequence as possible (even with 
c-style for loops most for loops tend to be finite in a way that you can 
predict the number of loops before they run if you want to), whereas while 
loops can be considered designed to fail, at least that’s how I was taught to 
use them. Of course both can be infinite and there’s overlap in how they’re 
used, but this is how I think about them, and thus what shapes conditions 
placed upon them.

Again though, if there’ll only be one loop with a where clause like this then 
I’m not sure it’s as much of an issue.


The obvious solution to clarity or lack of implied meaning is to either add 
detail (which narrows the gap on guard continue) or rename the keyword to 
something. In terms of the clarity I’m actually disappointed that Swift doesn’t 
use the do keyword for loops, as I find the following very clear:

        for eachValue in theValues where eachValue.isOdd do { … }

Reading the last part in isolation “where eachValue.isOdd do” is clearer that 
the block is skipped, but that the loop isn’t. This is essentially how I read 
loop blocks already, but since we have a “do” keyword I wish we could use it 
like this, as I would on all my loops. In fact, with the do present you could 
easily shorten “where” to “if”, which may even be slightly clearer still:

        for eachValue in theValues if eachValue.isOdd do { … }

This is part of why I’m uncertain about relocating where, as I kind of feel 
that it’s actually in the right place already, since the where clause 
determines whether the block is executed, not whether the loop stops, i.e- the 
program will still visit every element of the sequence if it can, you’re just 
choosing which ones to actually do work for. Even clearer still if you consider 
it with a comma in the middle like so:

        for eachValue in theValues, if eachValue.isOdd do { … }

Not really proposing this is a syntax, though if it were possible to write this 
way today it’s what I’d do, but the last form above is how I ready a where 
clause on a for loop. I’ve said that it’s equivalent to a guard because a guard 
is a nice way to replace it when the condition becomes more complex (or you 
need to break instead), but actually I’d say it’s more equivalent to:

        for eachValue in theValues { if eachValue.isOdd {
                …
        }}

Except I’d never want to write my code that way if I can avoid it (I frequently 
write code like this for switch statements inside enums, which is I’m eager to 
see a replacement to switch self, but that’s another issue entirely).


Also, one thing to add is that I really hate writing extra lines if I don’t 
have to; obviously I’ll do it when a single line gets too complex and 
cluttered, but one reason I like where is that I don’t have to waste a line 
inside the loop on a guard statement, which either keeps the focus on the code, 
or lets me instead use the line for a comment that clarifies my intent exactly; 
I’m all for self-documenting code, but a comment stating what my aim is better 
since any mistake in my code could leave my intent in question otherwise.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to