So now all I'd like in Erlang is...

Shawn Pearce <>
Thu Feb 19 01:27:03 CET 2004


Chris Pressey <> wrote:
> On Tue, 17 Feb 2004 19:58:25 -0500
> Shawn Pearce <> wrote:
> 
> > I've often wondered why Erlang code is:
> > 
> > 	foo(X) ->
> > 		ok.
> > 
> > and not:
> > 
> > 	Foo = fun(X) ->
> > 		ok
> > 	end.
> > 
> > with call sites using:
> > 
> > 	Foo(x).
> > 
> > instead of:
> > 
> > 	foo(x).
> > 
> > In other words, why are named functions different from lambdas?  Why
> > not make all named functions actually global variables which are
> > assigned to a lambda when the module loads?
> 
> How would that work w.r.t. dynamic code reloading?

I think it would work just like it does now.  The only difference is
that when a module is loaded, rather than registering its exported
functions in a table, a module is actually executed.  Thus modules
are more like this (once the compiler gets done with them):

fun() ->
	code:register_module(my_module),
	SomeConstant = "this is a constant string",
	code:register_module_function(my_module, foo, fun(X) ->
		SomeConstant ++ " " ++ atom_to_list(X)
	end)
end.

Or something.  :)  The code server basically runs the module when
it loads it, allowing the other funs in that module to get put into
the symbol table, and the constants to be created.

So external calls would still resolve like they do now, its just
that the symbol table used to resolve them is built of funs rather
than functions, which are more or less like named funs, but without
environment tagging along.

Since Erlang is single assignment, the environment is ok to have, its
just constants which you want to resolve at runtime.  Each time the
module loads, the constants are reconstructed and stored in the
environments.  This might be very tough to do in implementation with
the private heap BEAM, because there is no global data...

I can think of uses like:

	PrivDir = code:priv_dir(gen_serial),
	
	open = fun(Name) ->
		open_port({spawn, PrivDir ++ "/bin/serial_esock.exe"} ...)
	end.

Would be nice to do.  Today we do:
	
	open(Name) ->
		open_port({spawn, priv_dir() ++ "/bin/serial_esock.exe"} ...).

	priv_dir() ->
		code:priv_dir(gen_serial).

Not very different at all, and equally easy to write.  Just the runtime
implications are a little different (in more ways than just
performance).  But from a semantic consistentancy point of view, I just
gotta ask the question of why are functions different from funs?  :-)

-- 
Shawn.

  Delay is preferable to error.
  		-- Thomas Jefferson



More information about the erlang-questions mailing list