Description
Someone recently tweeted their frustration at for
loops in CoffeeScript, and particularly this nasty case:
console.log x for x in y by -1
is an infinite loop for any array y
, as this output makes clear:
for (_i = 0, _len = y.length; _i < _len; _i += -1) {
x = y[_i];
console.log(x);
}
As you can see, the index is set to 0, then counts down from there until it hits y.length
.
I understand the historical reasons for this: by
is only intended to be used in conjunction with the for...in range
syntax. So the easy fix would be to simply throw a syntax error when by
is used with the for...in arr
syntax.
But we can do better by supporting for...in arr by step
, where step
is a constant:
- If
step
is a positive integer value, keep the current behavior. It's fine. - If
step
is a negative integer value, set the initial index toy.length - 1
instead of to0
and make the loop criterion_i >= 0
; there's no need for_len
. - If
step
is any other value (e.g.0
or0.2
), throw a syntax error.
Variable step
values should also probably be supported, though I'm not sure how zero/non-integer values should be handled; maybe the best approach is to just assume that the user knows what they're doing, in which case the compilation can be to something like
for (_len = y.length; _i = step > 0 ? 0 : len - 1; step > 0 ? _i < _len : _i >= 0; _i += step) {
x = y[_i];
console.log(x);
}