[swift-evolution] Add a while clause to for loops

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 8 18:31:10 CDT 2016

On Wed, Jun 8, 2016 at 4:44 PM, Haravikk <swift-evolution at haravikk.me>

> On 8 Jun 2016, at 17:11, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> On Wed, Jun 8, 2016 at 3:38 AM, Haravikk <swift-evolution at haravikk.me>
> wrote:
> Yes this could be handled by an if/guard statement with continue, and
>> while as proposed here could be done with the same plus a break, but these
>> things come up so often that it just makes a lot of sense to get it all
>> neatly onto one line.
> As I pointed out above with Tim's example, putting it all on one line is
> absolutely not 'neat'--it reads like spaghetti. That is one major beef I
> have with this proposal: that it *encourages* writing on one line too many
> things that, whether you use `where` or not, are much more clearly written
> on multiple lines. If writing everything on one line is for you the major
> advantage of this proposal, we could agree on everything else and I would
> be very much opposed to this proposal on that basis alone.
> I’m not proposing that every single loop have all of its conditions
> crushed onto one line, just like I wasn’t when discussing where on the
> condition clause thread. The usefulness of where and the proposed while is
> in the common, simple cases, for example:
> for eachValue in theValues while eachValue < 100 where eachValue % 2 == 0
> { … }
> The alternatives would be:
> for eachValue in theValues {
> guard eachValue < 100 else { break }
> guard eachValue % 2 == 0 else { continue }
>> }
> for eachValue in theValues.prefix(while: { $0 < 100 }).filter({ $0 % 2 ==
> 0 }) { … } // Could also be on multiple lines
> The former wastes vertical space for what it does IMO; it’s fine if the
> conditions were more complicated, but since they’re not where/while is
> ideal. The second isn’t terrible, but it’s a pretty noisy way to handle
> common loop conditions.

We've rehashed this a few times. The version with guard statements is what
I argue is the ideal. Perhaps you can prove me wrong, but I have never
heard anyone enunciate a principle regarding conservation of vertical
space. Line length, however, there's been tomes written about that.

The last version is unreadable to me, because it's too long; the first
version with your proposed syntax suffers the same defect, but has fewer
punctuation marks.

> The use of where/while isn’t about eliminating either of these
> alternatives, they’re absolutely useful in cases where their drawbacks
> become advantages. For example the inline guards are great when the
> conditions are more complex, and necessary if you want to do more than the
> simple cases allow. The second form is best when you need more than the two
> methods, alternate methods, or you have predicates you can pass in
> directly, although personally when I do this I tend to do the chinning on
> its own lines outside of the loop, leaving me with a loop of: for eachValue
> in theFilteredValues { … } or whatever.

Yes, that's a good option as well IMO.

> Closures are--I'm sure you'd agree--a far more advanced concept than
> loops. Concepts like closing over a variable are very, very hard. Many
> useful things can be written without using closures. Not so many things
> could do without loops. It very much matters that a learner might feel that
> he or she cannot understand everything about a loop with the handwavy
> explanation that it'll "come later”.
> Not my point at all; my point was about the shorthand for closures not
> closure as a whole, you can’t learn the closure shorthands without first
> learning what a closure is.

Neither here nor there, but what you call a "closure shorthand" is a
shorthand for functions in general; you can absolutely write something in
that shorthand that doesn't close over anything in the outer scope (making
it, by definition, not a closure). And it is definitely possible, with
trailing closure syntax, to write a closure without learning what it is.
Consider, for example, the future `queue.async { ... }`.

> In exactly the same way where/while are just be shorthands for inline
> if/guard, you don’t need to learn about these clauses to make a functioning
> loop if you know how to do it with your if/guard statements. In fact it’s
> better to learn it in this order as once you know what each clause is a
> shorthand form of (if/guard continue or break) then you know exactly what
> it does already.

Learning to code involves not just learning what you'll use but also
understanding other people's code when you read it. As I mentioned above, I
have seen a student helpless with frustration because he could not
understand what the ++ operator does (in his case, in Java). More
accurately, he understood the fact that it's a shorthand and what it's a
shorthand for, but he could not see a rationale for its existence and
concluded that he must be misunderstanding some major concept regarding
operators in general. It was a huge stumbling block, not because he was
incapable of learning this syntax but because the syntax seemed
unnecessarily redundant and illogical. "There must be something else going
on," he insisted over and over.

> Ignoring for a moment that you’re opposed to the where clause in general,
> what would your thoughts be on only permitting one of where/while in a for?
> i.e- you would be able to do only one of:
> for eachValue in theValues where eachValue % 2 == 0 { … }
> for eachValue in theValues while eachValue < 100 { … }
> But not have both a where and a while on the same line. This eliminates
> the question mark around the order they are applied in, while still giving
> us the ability to essentially switch the behaviour of the where from
> continue to break. I’m not decided whether I want both in a single
> statement or if I just want to be able to choose between them. It also
> limits how much goes on one line as you have to use an inline condition to
> achieve both for a single loop.

I could live with that, although maybe I would want to explore different
words, as they do look very similar visually. I think this will also
depend, as Erica says, on the outcome of SE-0099.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160608/e69767e6/attachment.html>

More information about the swift-evolution mailing list