[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