[Fwd: A small problem in lazy-evaluation.]

Joe Armstrong joe@REDACTED
Mon Mar 22 12:09:35 CET 1999


Hello,

	This is an answer to your question about lazy lists that you sent
to Anna [I've also cross posted to erlang-questions@REDACTED].

....

There were a number of problems with you program - they all stemmed from
the same error.

Your first function was wrong, recall that you wrote:

%% This generates a lazy sequence starting from K.
from(K) ->
    fun() ->
            [K| from(K+1)]
    end.

This is too lazy, you need a list with an eager head and lazy tail
like this:

from(K) -> [K | fun() -> from(K+1)].

I then changed the representation of a lazy list to the above form in
your program and it now works fine. I also added a function first(N)
which forces evaluation of the first N elemnts in the lazy list, so
you can see that it works. Just printing something in Erlang will
not force evaluation.

> p3:first(20).
generated:2
generated:3
generated:5
generated:7
generated:11
generated:13
generated:17
generated:19
generated:23
generated:29
generated:31
generated:37
generated:41
generated:43
generated:47
generated:53
generated:59
generated:61
generated:67
generated:71
true


         /Joe

Here's the modified program

-module(p3).
-export([from/1,filter/2,sift/2,sieve/1,primes/0, first/1]).

%% This generates a lazy sequence starting from K.
%% from(K) ->
%%    fun() ->
%%	    [K| from(K+1)]
%%    end.

from(K) -> [K|fun()->from(K+1)end].


%% This applies the Pred to each element of the list and returns a list
%% containing those elements which satisfies Pred.

filter(Pred,[]) -> [];
filter(Pred,[H|Tl]) ->
	  case Pred(H) of
	      true ->
		     [H|fun() -> filter(Pred,Tl()) end];
              false ->
		  filter(Pred,Tl())
          end.

%% This function simply calls filter/2.
sift(P,L) -> filter(fun(N) -> N rem P /= 0 end,L).

%% This generates a lazy list after removing all the multiples of H.
sieve([H|Tl]) -> 
	[H|fun() -> sieve(sift(H,Tl())) end].


%% This generates the list of prime numbers.
primes() -> sieve(from(2)).

first(N) -> first(N, primes()).

first(0, _) -> true;
first(N, [X|P]) ->
	io:format("generated:~p~n",[X]),
	P1 = P(),
	first(N-1, P1).

	/Joe

PS - questions about erlang are best sent to
erlang-questions@REDACTED - read http://www.erlang.org/faq.html 
for more information about this list.



--
Joe Armstrong  Computer Science Laboratory  +46 8 719 9452
AT2/ETX/DN/SU  Ericsson Telecom SE-126 25 Stockholm Sweden 
joe@REDACTED    http://www.ericsson.se/cslab/~joe 







More information about the erlang-questions mailing list