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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jun 7 18:02:47 CDT 2016


On Tue, Jun 7, 2016 at 5:11 PM, Tim Vermeulen <tvermeulen at me.com> wrote:

> I’ve been thinking about this for a bit now, and I think it would make
> most sense to evaluate these clauses from left to right. However, cases
> where the order matters are very uncommon, and I would rather have the
> power to choose which clause is evaluated first than to have a forced
> default order. Either way I don’t see this as a reason not to allow
> combining the two clauses because IMO it can lead to some very clean code.
> For instance, say we want to loop through all even fibonacci numbers below
> 4 million  (see problem #2 from project euler), we could do this:
>
> `for number in fibonacci where number % 2 == 0 while number < 4_000_000 {
> }`
>

This statement looks like spaghetti to me. I would not at all support
extending the language to permit it. Do you really think it's more readable
than going step-by-step?

```
let numbers = fibonacci.prefix { $0 < 4_000_000 }
for number in numbers where number % 2 == 0 {
  // ...
}
```

or just:

```
let numbers = fibonacci.prefix { $0 < 4_000_000 }
let evens = numbers.filter { $0 % 2 == 0 }
for number in evens {
  // ...
}
```


> I could have ordered the two clauses in any way I want. If combining the
> clauses weren’t allowed, I’d have to put (at least) one of them inside the
> block, which would be a (minor) pain.
>
> I don’t currently have a very strong opinion about the order of
> evaluation, so I might be convinced otherwise. But combining the two
> clauses is so powerful that I don’t think it’s worth to get rid of just
> because of an edge case.
>
> > It may be workable if you can have only one or the other, but mixing and
> matching them as proposed above would be a world of hurt:
> >
> > ```
> > for foo in bar where condition1 while condition2 { ... }
> > ```
> >
> > If condition1 and condition2 both evaluate to true, then whether you
> continue or break would depend on the relative order of where and while;
> for generality, you would want to allow both `for...in...where...while` and
> `for...in...while...where`, and likely `for...in...while...where...while`,
> etc. There is nothing in the meaning of those words that would suggest that
> `while...where` behaves differently from `where...while`, etc. This is why
> words like "break" and "continue" are IMO far superior.
> >
> >
> > On Tue, Jun 7, 2016 at 2:34 PM, Erica Sadun<erica at ericasadun.com(mailto:
> erica at ericasadun.com)>wrote:
> > >
> > > > On Jun 7, 2016, at 1:16 PM, Tim Vermeulen via swift-evolution<
> swift-evolution at swift.org(mailto:swift-evolution at swift.org)>wrote:
> > > > > The meaning of the proposed while is not at all a pair for where,
> since where clauses in while loops would do the same thing as while clauses
> in for loops. That's crazy.
> > > >
> > > > It sounds crazy, but it’s the nature of the while loop. A where
> clause in a while loop also has a different result than a where clause in a
> for loop.
> > >
> > > The where_clause appears in the for in statement
> > >
> > > for_in_statement : 'for' 'case'? pattern 'in' expression where_clause?
> code_block
> > >
> > > It's syntactic sugar because the expression can be already be limited
> through functional chaining of some sort or another. At the same time, it's
> nice and pleasant to have `where` and I'm not itching to throw it out. The
> same courtesy could be easily extend to `when` (because I don't really want
> to use the `while` keyword here, but I could easily be convinced otherwise
> because I don't have a strong stance either way):
> > >
> > > for_in_statement : 'for' 'case'? pattern 'in' expression (where_clause
> | when_clause)? code_block
> > > when_clause : 'when' expression
> > >
> > > and again it could be nice and pleasant to have, although not
> necessary. The question comes down to how much does the language benefit by
> this sugar.
> > >
> > > I'd say that in both cases, combining chaining and statements is
> marginallyless goodthan either using standalone chaining or statements
> without chaining. But as I say this, I know as a fact, I fully intend to
> use `sequence(_:, next:).take(while:)` with for0in statements, so I'm
> starting from a hypocritical vantage point.
> > >
> > > To summarize, I'm more +0.01 than I am -0.01 on this.
> > >
> > > -- E
> > > p.s. Sorry, wux
> > >
> > >
> >
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160607/b3139dd2/attachment.html>


More information about the swift-evolution mailing list