| Author |
Message |
< Erlang ~ Code replacement and fun expressions |
| jwatte |
Posted: Fri Mar 19, 2010 10:05 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
Is it the case that any fun closure will become invalid once the module it was defined in has been reloaded twice?
Specifically:
Code:
-module(foo).
-export([make_fun/1, mutate/2]).
make_fun(Var) -> fun(X) -> foo:mutate(Var, X) end.
mutate(A, B) -> A+B.
If I build this and run it, and then reload foo twice, will a fun returned by make_fun/1 stop working?
I guess the question boils down to whether the implementation generates code for the lambda, or just generates an environment with a pointer to pre-generated code? |
|
|
| Back to top |
|
| bpuzon |
Posted: Sat Mar 20, 2010 11:56 am |
|
|
|
User
Joined: 05 Aug 2009
Posts: 23
Location: Cracow, Poland
|
Let's say you've done this:
Code: F = foo:make_fun(bar)
If you use dbg, you will see that F(bar) translates to:
Code: (<0.380.0>) call foo:'-makefun/1-fun-0-'(bar,bar)
You will invalidate F if the definition of foo:'-makefun/1-fun-0-' changes somehow. In particular, you can't change the fun's definition and, inside make_fun/1, you can't define any new funs before the one you already have.
However, I wouldn't rely on the current fun implementation rules and rather assume that any changes to make_fun will require the invalidation of F. |
_________________ Saludos,
Bartłomiej Puzoń
Erlang Solutions |
|
| Back to top |
|
| jwatte |
Posted: Sat Mar 20, 2010 3:49 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
Thanks for the hint about the debugger!
Then there's a follow-up question: the "mochiweb" application creates a fun() for the callback for web requests (the fun then calls a named/module-qualified function within the module), and starts an automatic reloader application that re-loads modules that have been changed.
I then assume this then means that you can only re-load your callback module once, before that fun will be invalidated and all future requests will be invalid? |
|
|
| Back to top |
|
| bpuzon |
Posted: Sat Mar 20, 2010 4:11 pm |
|
|
|
User
Joined: 05 Aug 2009
Posts: 23
Location: Cracow, Poland
|
| Could you provide a short example of the mochiweb's call sequence? Your description is a bit too complicated for me. |
_________________ Saludos,
Bartłomiej Puzoń
Erlang Solutions |
|
| Back to top |
|
| jwatte |
Posted: Sat Mar 20, 2010 4:45 pm |
|
|
|
User
Joined: 10 Feb 2010
Posts: 34
|
Here is the mochiweb skeleton module for a web app, which ends up being the module where you're supposed to develop your URL path dispatch:
Code:
-module(skel_web).
-author('author <author@example.com>').
-export([start/1, stop/0, loop/2]).
%% External API
start(Options) ->
{DocRoot, Options1} = get_option(docroot, Options),
Loop = fun (Req) ->
?MODULE:loop(Req, DocRoot)
end,
mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options1]).
stop() ->
mochiweb_http:stop(?MODULE).
loop(Req, DocRoot) ->
"/" ++ Path = Req:get(path),
case Req:get(method) of
Method when Method =:= 'GET'; Method =:= 'HEAD' ->
case Path of
_ ->
Req:serve_file(Path, DocRoot)
end;
'POST' ->
case Path of
_ ->
Req:not_found()
end;
_ ->
Req:respond({501, [], []})
end.
Specifically, "Loop" is a fun expression defined in this module, which calls this module itself. It's an argument to the mochiweb framework -- each time a request comes in, mochiweb will spawn a new process and call the fun within the context of that process to handle the request.
I was seeing a problem where the server would stop responding after updating and re-compiling this module a few times. It seems pretty clear that the reason is that the fun passes as argument is becoming invalidated when the initial version of the module goes from "old" to "purged."
In most other languages with closures (Python, JavaScript, Scheme, etc), the code for a closure lives "forever," and module definitions (and parts thereof, such as individual versions of function definitions) are simply garbage collected like anything else. This different behavior of Erlang confused me as a newbie until I understood what's going on. |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|