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

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 8 14:07:12 CDT 2016


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

> On Wed, Jun 8, 2016 at 1:58 PM, Tim Vermeulen <tvermeulen at me.com> wrote:
>
>> That’s why I said “potentially less elegant”, some people might prefer
>> `where` over `guard`. This proposal would give them the choice (in very
>> specific situations) to use `where` rather than `guard` if they don’t want
>> to sacrifice performance.
>>
>
> Since Swift strives to be an opinionated language without dialects, there
> shouldn't be more "choice" but rather one general solution, IMO. Since
> `guard` doesn't sacrifice performance and is the most general, I would
> oppose adding the option of `while` to offer more choice.
>

I should add, on the topic of removing `where`, there would be a higher
threshold for a successful proposal and I would have to convince people
that the `where` clause is actually harmful. I do wonder if I could succeed
in that endeavor. But when it comes to adding something like `while`,
you've yet to convince me it offers more than just stylistic choice. IMO,
that is insufficient for a proposal as consequential as adding syntax to
the language itself (a much more serious addition than changing API in the
stdlib, for example).


>
>
>>
>> > On Wed, Jun 8, 2016 at 1:35 PM, Tim Vermeulen via swift-evolution<
>> swift-evolution at swift.org(mailto:swift-evolution at swift.org)>wrote:
>> > > This is a really strong argument in my opinion. If we don’t add a
>> `while` to for loops, then in some situations we will have to rewrite a
>> `where` clause to something potentially less elegant, given that we don’t
>> want to give up performance.
>> > I disagree. I argue that what you call "less elegant", namely if (or
>> guard) inside the loop, is the most elegant solution.
>> >
>> > >
>> > > >IMO `.prefix` is just not the equal alternative for as proposed
>> `while` :
>> > > >in case of 'while' expression `number<4_000_000` will be calculated
>> > > >*only* for those who `number % 2 == 0`. In case of `prefix` - the
>> > > >expression will be processed for each `number` and only after this
>> filtered
>> > > >by `number % 2`. Let's assume we need to check for some
>> > > >veryExpensiveTest(number):
>> > > >
>> > > >for number in fibonacci where number % 2 == 0 while
>> > > >veryExpensiveTest(number) {}
>> > > >
>> > > >let numbers = fibonacci.prefix { veryExpensiveTest($0) }
>> > > >for number in numbers where number % 2 == 0 {}
>> > > >
>> > > >So, `while` for `for` loops just can't be always replaced with
>> `prefix`
>> > > >
>> > > >On 08.06.2016 2:02, Xiaodi Wu via swift-evolution wrote:
>> > > >>On Tue, Jun 7, 2016 at 5:11 PM, Tim Vermeulen<tvermeulen at me.com
>> (mailto:tvermeulen at me.com)
>> > > >><mailto: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)
>> > > >><mailto:erica at ericasadun.com>(mailto: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)
>> > > >><mailto:swift-evolution at swift.org>(mailto: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
>> > > >>
>> > > >>
>> > > >>
>> > > >>
>> > > >>_______________________________________________
>> > > >>swift-evolution mailing list
>> > > >>swift-evolution at swift.org(mailto:swift-evolution at swift.org)
>> > > >>https://lists.swift.org/mailman/listinfo/swift-evolution
>> > > >
>> > > >
>> > > >
>> > > _______________________________________________
>> > > swift-evolution mailing list
>> > > swift-evolution at swift.org(mailto: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/f5d373c7/attachment.html>


More information about the swift-evolution mailing list