[erlang-questions] currying and lazy evaluation questions

Jim Larson jim@REDACTED
Wed Sep 24 04:18:38 CEST 2008


In message <96D3B50792094B55A9AE7D2F65123797@REDACTED> you write:
John Hughes writes:
>> I read a note on the Internet that said "You can do lazy evaluation in 
>> Erlang (observe Erlang QuickCheck), but you have to be explicit about it."
>> ?
>> Can some one explain to me how to "explicitly" use lazy evaluation in 
>> Erlang, in the general?
>> ?
>
>I use macros
>
>-define(DELAY(E),fun()->E end).
>-define(FORCE(F),F()).

One aspect of many lazy functional implementations is that delayed
computations are memoized when forced - the evaluated result is stored,
so that in

    Promise = ?DELAY(expensive_computation(X, Y, Z)),
    Value1 = ?FORCE(Promise),
    Value2 = ?FORCE(Promise)

the expensive computation is only evaluated once.  This can have a
dramatic effect on the efficiency of lazy functional data structures,
as shown in Okasaki.

Sadly, there's no trick for getting this behavior in purely functional
code, since it involves a side effect.  However, one can throw processes
at the problem:
    
    delay(Thunk) ->
        spawn_link(fun() -> lazy_wait(Thunk) end).
    
    force(Lazy) ->
        Lazy ! {self(), force},
        receive
            {Lazy, Result} -> Result
        end.
    
    lazy_wait(Thunk) ->
        receive
            {Proc, force} ->
                Result = Thunk(),
                Proc ! {self(), Result},
                memo_loop(Result)
        end.
    
    memo_loop(Result) ->
        receive
            {Proc, force} ->
                Proc ! {self(), Result},
                memo_loop(Result)
        end.

I don't think that processes get garbage collected, so there's a
nontrivial problem of reclaiming resources.  This trick still might
be useful in some limitied settings, through.

Jim



More information about the erlang-questions mailing list