[erlang-questions] LFE - Lisp Flavoured Erlang released
Mon Mar 3 22:40:51 CET 2008
Yes Richard I remember most of this from the bad old days. :-)
What I was getting at was that there is no really no way to return a true
function pointer in the way that Scheme or CL can do. This is not a Core
problem but an Erlang implementation property. Even if doing
let MyCons = 'cons'/2 in apply MyCons(A, B)
is legal in Core as is generally using name/arity as data then unless these
are optimised away as you mentioned then a later pass in the compiler,
v3_kernel, actually converts them to a fun. In the Erlang implementation you
cannot directly reference functions as data.
I personally think that it was a Good Thing that name/arity function names
were kept in Core as it is a (mis)feature of Erlang and trying to hide this
would have led to strangeness. That is why I have kept in the distinction in
LFE and may even make it more noticeable. I am not yet decided either way.
Anyway letrec in LFE maps directly to letrec in Core, which works on
name/arity function names, so the following LFE code is perfectly legal and
works as expected:
(letrec ((f (lambda (x) (+ x n)))
(f (lambda (x y) (+ x (+ y n)))))
(list (f n) (f n 10)))
Though it might be hard explaining to people that it is legal. :-) At least
until they see it as Erlang and not as lisp. I don't really want to try and
hide properties of the underlying implementation, especially when you can't
really avoid seeing them. I mean I can define functions with the same name
with different arities so I will never be able to refer to a function by
just its name.
The Core Erlang spec, together with the record definitions, were a great
help in generating code. That together with writing Erlang code and seeing
what it resulted in.
On 02/03/2008, Richard Carlsson <richardc@REDACTED> wrote:
> 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,
> 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.
> 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).
> If you need human assistance to interpret some detail, just mail me.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the erlang-questions