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

Dany St-Amant dsa.mls at icloud.com
Tue Jun 7 19:52:42 CDT 2016


For most of of this discussion I have been for the introduction of 'while' and against the removal of 'where'; IMO, both help carry the intent of the code a bit better than the un-sugared version using if block (which can be mistaken for a regular condition)

for number in fibonacci
{
 if number % 2 == 0 { continue }
 if number < 4_000_000 { break }
 if number < 10 { print("small:", number) }
 else { print("large:", number) }
}

The issue with the 'where' and this new 'while' is that they may not be useable with the 'repeat' and 'while'-loop.

Thinking outside of the box, I was wondering if the 'where'/'while' could be move inside the loop code itself; but without tagging a 'continue' or 'break' it would be too confusing, as too disconnected from the 'for'

for number in fibonacci
{
 where number % 2 == 0
 while number < 4_000_000
}

And not sure how one could specify the loop label as now being free-standing, they can appear anywhere. So how about 'when ... continue|break' which is just pure sugar

label:
for number in fibonacci
{
 when number % 2 == 0 continue label
 when number < 4_000_000 break label
}

Not shorter than the 'if' variant, but I'm sure a some on the list would enjoy the curly brace free syntax.

Dany

> Le 7 juin 2016 à 19:26, Tim Vermeulen via swift-evolution <swift-evolution at swift.org> a écrit :
> 
> Interesting. What if you put newlines before `where` and `while`? It’s hard to get the spacing right in a mailing list, but I tried it in Xcode and it looks really good to me (except for the compiler error it currently produces). Way better than the way I wrote it initially and the alternatives you mentioned.
> 
> for number in fibonacci
>   where number % 2 == 0
>   while number < 4_000_000 { }
> 
>> On Tue, Jun 7, 2016 at 5:11 PM, Tim Vermeulen<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)>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)>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
> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list