[erlang-questions] Process declarations
Richard Carlsson
richardc@REDACTED
Thu Oct 5 17:32:43 CEST 2006
Thomas Lindgren wrote:
> Are the spawn(fun() -> ... end) functions safe for
> code change?
(That might have been a rhetorical question, but I think its worthwhile
to try to dispel some of the FUD around spawn and funs.)
As long as you use them like that (with the fun written explicitly
inline, or at least being created in the same module as the spawn), and
as long as the fun-body quickly does a *tail call* so that no stack
references point back to the fun, then the process is *not* sensitive to
code change (of the module containing the fun).
Writing a process like this, however, would be bad for you:
spawn(fun()-> m1:main(), m2:say_goodbye() end)
presuming the process will spend most of its time in main(), there will
be a reference to the code of the fun on the process stack until it
returns from main() and enters say_goodbye(). Even if the other
functions reside in separate modules, updating the code that contains
this fun will cause the process to die at the second code change when
the original code is forced out of the system.
*But*, that is a basic rule for writing code for long-running processes:
when they enter the code for the main loop (or state machine), they
should not have return pointers to other modules on their call stack.
The following would be the same kind of mistake as the fun above:
%% in module m0
start() -> spawn(m1, p, []).
%% in module m1
p() ->
m2:main(),
m3:say_goodbye().
because the process would be sensitive to updates of m1, even though it
spends almost all of its lifetime in m2 and m3.
If you do something like this:
run(F) -> spawn(F).
where F might come from some external source, then of course the fun F
might be dead already when you try to do the spawn - but that is no
different from this kind of code:
run(F) -> F().
If you need to store funs for some time (so that code change might
happen meanwhile), then use the form "fun m:f/n", which is not sensitive
to code changes, and has no problem with being passed from one node to
another.
What I'm trying to say is basically: don't be afraid of funs - they are
not the problem. Engage brain before writing process code.
/Richard
More information about the erlang-questions
mailing list