urn
urn copied to clipboard
range :by is one too high?
core/list/range
To me it makes sense if
> (range :from 1 :to 10) out = (1 2 3 4 5 6 7 8 9 10)
was a shorthand for
> (range :from 1 :to 10 :by 1)
but it is not, it is a shorthand for
> (range :from 1 :to 10 :by 2) out = (1 2 3 4 5 6 7 8 9 10)
In fact, running
> (range :from 1 :to 10 :by 1)
causes an infinite loop which could be guarded against. Since it cant be negative may as well guard against :by (n < 1) too.
So this is technically working as expected, it's just very bad naming. range
takes after Haskell's range operators. Where [1,3..9]
is a shorthand for [1,3,5,7,9]
. You can see this in the doc string:
> (range :from 1 :to 10)
out = (1 2 3 4 5 6 7 8 9 10)
> (range :from 1 :to 10 :by 3)
out = (1 3 5 7 9)
Really what you want is something like Python's range function (or just Lua/Urn's for
loop), where it takes a step instead. Maybe we should also accept a :step
parameter which provides this behaviour.
Perhaps :then
is a better name for :by
. For example:
(range :from 1 :then 3 :to 9)
could translate to Haskell's [1,3..9]
.