[erlang-questions] lists:seq/[2,3] bug?
Richard A. O'Keefe
ok@REDACTED
Fri Sep 19 04:30:33 CEST 2008
On 18 Sep 2008, at 10:21 pm, Zvi wrote:
> 1. if you already dealing with it, can you also extend it to floats
> too?
> I.e. if step is float, then the resulting list must be floats too.
Let me explain why this was an issue for me.
I sometimes do things in Haskell and sometimes in Erlang.
[3..2] is an empty list in Haskell.
It makes life just that little bit harder if I can't do that in Erlang.
Haskell does support [a..z] and [a,b..z] for floating point numbers.
Since (a) floating-point loops are a little bit tricky
(taking X[i+1] = X[i]+delta and
taking X[i] = X[0]+i*delta
give *different* answers, with the latter being slightly more
accurate,
and IEEE hasn't fixed all portability issues
) and (b) in current Erlang, lists:seq/2 and lists:seq/3 provide type
information for the Dialyzer, which I for one would be very reluctant
to break,
I suggest that the way to handle floating point ranges would be to
add two new functions:
lists:float_seq(First, Last)
lists:float_seq(First, Last, Inc)
> 2. I'm all about common sense, and behaviour we expect must be
> consistent
> with similar constructs in other languages from Basic to Matlab.
> Python's "range([start,] stop [,step]) -> list of integers"
> construct is
> not a good example, b/c "stop" isn't included (which is counter-
> intuitive)
> and it's also defined only on integers. See example at the end of the
> message.
To every example there is an equal and opposite example.
In R, if x <= y, then x:y is x,x+1,...,y
but if x < y, then x:y is y,y-1,...,x
so that 1:3 is 1 2 3, 1:2 is 1 2, 1:1 is 1, but 1:0 is 1 0.
(This may be the most hated thing about R, that 1:n does not work
when n might be 0, so you have to say seq(from = 1, length = 0).)
Haskell provided the motivation, but the reason I how to persuade
Erlangers to make lists:seq(X, X-1) return [] is to make Erlang
more consistent with ITSELF.
>
> 3. Step = 0
> Also Erlang handles well case when Step=0, while both Matlab and
> Python not:
Oddly enough, [1..1] => [1] in Haskell,
but [1,1..1] => [1,1,1,1,1,1,1,1.......
I see Step = 0 as very much a special case; it doesn't really fit well
with the rest of the specification. However, I certainly don't want
to break any code that might rely on it.
> 3. Syntax.
> Also will be good to have operator or parse-transform, which
> converting
> something like "[N..M]" to "lists:seq(N,M)" or "[N1,N2..M]" to
> "lists:seq(N1,M,N2-N1)"
It's pretty, certainly. I think we can do without it, though.
> 4 Is this possible to have iterator or lazy evaluated sequence in
> Erlang?
> I.e. in code like this:
>
> Sum = lists:sum( [X*X || X<-lists:seq(1,1000000)] ).
>
> Do I really need to allocate list of 1000000 elements, just to be
> able to
> use List Comprehension construct?
We don't need special purpose evaluation strategies for this,
just for the compiler to recognise X <- lists:seq(A, Z[, D]) and
do something special with it. In this case, you have *two* lists
that you don't need, and
sum(First, Last, F) ->
sum_loop(First, Last, F, 0).
sum_loop(First, Last, F, S) when First =< Last ->
sum_loop(First+1, Last, F, S + F(First));
sum_loop(First, Last, _, S) when First > Last ->
S.
...
Sum = sum(1, 1000*1000, fun (X) -> X*X end)
isn't _that_ hard to come up with. It would be nice to have an Erlang
compiler that did cross-module inlining and deforestation. It's not
going to happen soon.
> 5 Last thing, I think that function like this must be implemented in
> native
> code in the VM itself, like lists:reverse.
My concern here is whether the function(s) should have a value or not
in certain cases. However, it's always a good idea to try things.
Imagine my surprise, on a Mac (and therefore without HiPE), to find
that reverse/1 coded in Erlang was only 3 times slower than the
built-in one. On a SPARC, loaded with c(...,[native]), the result
was 2 times slower than the built-in one, but I had to use
ridiculously long lists to measure it. (And there's even one test
result, with length 100*1000, where the Erlang code was faster...)
List reversal turns up a lot more than sequence generation, so it
makes sense to speed that up, even if it is just by a factor of 2.
More information about the erlang-questions
mailing list