[erlang-questions] LFE - Lisp Flavoured Erlang released

Richard Carlsson richardc@REDACTED
Sun Mar 2 13:15:31 CET 2008


Robert Virding wrote:
> Function bindings
> -----------------
> 
> Core Erlang (and Erlang and the BEAM) separate variable and function
> bindings. A function binding has a name and an arity, this is a result
> of allowing different functions to have the same name but different
> number of arguments. Also there is no concept of a function reference
> built into the Core and BEAM. It is therefore impossible to get a
> reference to a function and pass it around, creating a fun which calls
> this function is not the same thing. So code like:
> 
> In CL: (funcall #'cons a b)
> In Scheme: (let ((my-cons cons)) (my-cons a b))
> 
> CANNOT work in Erlang.

I think you can relax, Robert. This is not a problem.

In plain Erlang, you'd write

     MyCons = fun cons/2,
     MyCons(A,B)

In Core Erlang, you write it like this:

     let MyCons = 'cons'/2 in apply MyCons(A, B)

Neither of these things mean that you'll necessarily get another
closure that will delegate the call - that's an old implementation
detail, which is not universally valid anymore. (E.g., with inlining
enabled, this will reduce to a direct call "cons(A, B)".) And in
particular, there is just a single variable namespace.

You're right that Core Erlang has no special notation ("fun f/N") for
referring to a function (as opposed to defining it) - that's because the
keyword "fun" is not needed. Core Erlang has two flavours of variables:
normal Erlang-style variables, and 'atom'/integer function names. (We
could actually have used only the first form, but then the Core Erlang
code would be harder to understand, and the export section would have to
look something like "export [ F17 as 'foo'/2, F32 as 'bar'/1, ... ]".)
You can only define function-name variables in letrec-expressions, not
in let-expressions, but this is no limitation in general, since you can
easily bind a plain variable to a function-name variable, as above.

The main point here is: when you see some expression "'f'/3" in Core
Erlang or "fun f/3" in Erlang, think of it as just a name, a variable.
Forget about how "fun f/3" was originally implemented. This is one of
the big things about Core Erlang: except for when you need to create
names of exported functions, that will be visible outside the module,
a variable is just a reference to some value, functional or not, and
it does not matter whether it was defined in a letrec or a let. This
makes it much easier to do transformations like inlining on the Core
language level.

     /Richard

PS. I know that it's not easy to grok the full consequences of the Core
Erlang specification; one has to sort of clear one's mind and start from
scratch - if the spec doesn't prohibit something, then it should just
work (assuming that the compiler doesn't have a bug or is incomplete).

[http://www.it.uu.se/research/group/hipe/cerl/doc/core_erlang-1.0.3.pdf]

If you need human assistance to interpret some detail, just mail me.




More information about the erlang-questions mailing list