I was wondering about slightly different JavaScript which ranges comprehensions in CoffeeScript compiles into. Is there any reason why following differencies in generated JavaScript?
Iterating a range by integer step
numbers = (i for i in [start..end] by 2)
compiles into:
for (i = start; i <= end; i += 2) {
_results.push(i);
}
But when iterating by fractional step
numbers = (i for i in [start..end] by 1/2)
generates bit more complicated JavaScript:
for (i = start, _ref = 1 / 2; start <= end ? i <= end : i >= end; i += _ref) {
_results.push(i);
}
So why this additional start <= end condition?
You’ll get similarly elaborate code if you just do
numbers = (i for i in [start..end]). This is because CoffeeScript doesn’t know which direction the range goes when the beginning or ending is a variable. The compiler has a special optimization where it will output simpler code if a constant step is provided, but unfortunately 1/2 is counted as an expression rather than a constant.