[erlang-questions] funs and code loading

Matthias Lang <>
Thu Jan 17 01:08:13 CET 2008


Hi,

for the record: I think your explanation is confusing and wrong.

I expect section 9 of the Barklund draft to apply. It explains how
code loading is supposed to work. The changeover from old to new code
is only supposed to occur in remote calls. f() is not a remote call. 
A = fun f/0, A() is not a remote call either. So no changeover should be
happening in those cases. Yet it does.

Matthias

----------------------------------------------------------------------

Attila Babo writes:
 > Let's simplify your example to mark the difference:
 > 
 > loop() ->
 >     A = fun f/0,
 >     io:fwrite("~p ~p ~p~n", [A(), f(), ?MODULE:f()]),
 >     timer:sleep(3000),
 >     loop().
 > 
 > This will print "2 1 2" after changing VERSION from 1 to 2, because
 > the A = fun f/0 binding is dynamic at the function scope in run time,
 > while the call to f as f() at the next line is local and bound at
 > compile time. Recursion is through our original loop function, so f()
 > remains the same, while at each call A binds to the latest code. If we
 > do recursion at the last line with a ?MODULE:loop() global call, then
 > the local call of f() will bound to the actual code version and the
 > function will print "2 2 2" after code reloading.
 > 
 > In your original example the loop calls itself as loop(E, F, G, H),
 > here all of these variables goes out of scope and bind again to the
 > latest version at that time. This has the same effect as
 >     loop(fun ?MODULE:f/0, fun() -> f() end, fun f/0, fun() -> ?VERSION end).
 > As we are calling the original module's loop function the static value
 > of VERSION remains the same while f itself changes, so these print "2
 > 2 2 1" after code change.
 > 
 > It has an interesting side effect if we do recursion with a
 > ?MODULE:loop call. Here the first function will print "2 2 2 1" after
 > code change, as the original module's version, but after that this
 > will switch to our latest code so the output changes to "2 2 2 2".
 > 
 > As we can have only two versions of the same module after our second
 > change code server purges out the original module, so this example has
 > a limited use, but good for demonstration. I just hope that all these
 > make sense and I'm not making ideology for a bug:-). Please correct me
 > if I was wrong!
 > 
 > Attila
 > 
 > -----------
 > 
 > -module(reload).
 > -export([go/0, f/0, c/0]).
 > -export([loop/0]).
 > -define(VERSION, 1).
 > -vsn(version_1).
 > 
 > go() ->
 >   spawn(fun() -> loop() end).
 > 
 > f() ->
 >   ?VERSION.
 > 
 > loop() ->
 >   A = fun f/0,
 >   io:fwrite("~p ~p ~p~n", [A(), f(), ?MODULE:f()]),
 >   timer:sleep(3000),
 >   loop().
 > 
 > c() ->
 >   code:purge(?MODULE),
 >   code:load_abs(?MODULE).



More information about the erlang-questions mailing list