[swift-evolution] [Review] SE-0007 Remove C-style for-loops with conditions and incrementers

Michel Fortin michel.fortin at michelf.ca
Thu Dec 10 13:57:48 CST 2015


Le 10 déc. 2015 à 13:20, thorsten at portableinnovations.de a écrit :

> do {
>     func body(i: Int, _ j: Int) {
>         if i % 2 == 0 { return } // simulating continue
>         print (i, j)
>     }
>     var i = 10
>     var j = 20
>     while (i > 0 && j > 0) {
>         body(i, j)
>         i -= 1
>         j -= 2
>     }
> }

This is actually worse than the while loop I suggested. Now you can't break from the loop, nor return from the outer function, and continue has to be replaced by return.


> A nicer alternative would actually be the for-in loop:
> 
> for (i, j) in zip(10.stride(to: 0, by: -1), 20.stride(to: 0, by: -2)) {
>     if i % 2 == 0 { continue }
>     print(i, j)
> }

Nice. :-)

But depending on the perspective, this can be harder to read. You have to be familiar with zip and stride, as well as with sequence types in general, to understand what the above loop does. The C-style for loop version, or even the while loop version, is easier to interpret: you just look at the loop header and figure out how each value change over each iteration.

There's another reason someone could want to avoid the for-in version above: performance relies entirely on the optimiser inlining everything. There's a much higher risk of an unforeseen cost hiding somewhere when a loop is abstracted this way. Performance will be fine in most cases, but if for some reason the optimizer fails you and that loop really has to be fast, you'll need to rewrite the loop at a lower level.


-- 
Michel Fortin
michel.fortin at michelf.ca
https://michelf.ca



More information about the swift-evolution mailing list