[swift-evolution] A (better) Swift Equivalent For The Classical For-Loop With Numeric Scalars

William Dillon william at housedillon.com
Wed Mar 23 20:59:38 CDT 2016


> On Mar 23, 2016, at 6:46 PM, Dany St-Amant via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> Le 22 mars 2016 à 21:19, William Dillon <william at housedillon.com <mailto:william at housedillon.com>> a écrit :
>> 
>>> 
>>> These may be compact, but some programmer may fell that they are not in control: do these "stdlib" seq(), c.filter() pre-calculate all the entries (wasting precious cpu cycle if one break out early)  or are each value dynamically created? Having an explicit legacy loop format gives a feel of control. So something like
>>> 
>>> for i from 2 to 1_000_000 by 1 where i % 2 != 0 while foundCount < 5 { print(i); foundCount +=1 }
>>> 
>>> sounds less magical and seems easier to predict than
>>> 
>>> for i in 2.stride(to:1_000_000, by:1).filter({ $0 % 2 != 0}).prefix(5) { print(i) }
>>> 
>>> and is still quite readable, even if it mixes for loop, while loop and even simple condition.
>>> 
>> 
>> I disagree.  I think the first case is venturing dangerously close to the AppleScript “uncanny valley” of human language-like programming verbs where I never know the exact words and exact order for things.  The second example is right out of any functional programming mold, and I fully understand what’s happening, and how to decompose the process to test assumptions.  Also, I know how to implement the second case (more or less) from scratch, and that’s pretty huge for me.
>> 
> 
> There have been multiple fights over too verbose versus too terse, and on whether or not making it sound like English. I would agree a verbose syntax for a mandatory statement is a pain, but the while and where above are optional. And using them instead of relying on continue or break allow for code intent to be bit clearer.
> 
> Reusing my bad example, without the from/to/by:
> 
> for i in 2.stride(to: 1_000_000, by: 1)
> {
> 	if i % 2 != 0 { continue }
> 	print(i)
> 	foundCount += 1
> 	if foundCount >= 5 { break }
> }
> 
> // Where clause already work in current Swift
> for i in 2.stride(to: 1_000_000, by: 1)
> where i % 2 == 0
> {
> 	print(i)
> 	foundCount += 1
> 	if foundCount >= 5 { break }
> }
> 
> // While do not exist yet in this context
> for i in 2.stride(to: 1_000_000, by: 1)
> where i % 2 == 0
> while foundCount < 5
> {
> 	print(i)
> 	foundCount += 1
> }
> 

The ‘where’ I can tolerate because there are other examples of such a construct in other parts of the language.  The while part is still problematic, because where have you declared it?  Do you think declaring a variable for that somewhere outside the context of the loop is cleaner than leaving it entirely within that scope then doing a test and break?

- Will

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160323/653907b0/attachment.html>


More information about the swift-evolution mailing list