[erlang-questions] clarify: variable as function name

Andreas Hillqvist <>
Mon Dec 10 16:13:49 CET 2007


I have read the documentation:
    The following fun expressions are also allowed:
        fun Name/Arity
        fun Module:Name/Arity

    In Name/Arity, Name is an atom and Arity is an integer.
    Name/Arity must specify an existing local function.
    The expression is syntactic sugar for:
        fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end

Which dose not state that Module and/or Name could be variables containing atom.
So I guess I am proposing an addition to Erlang and should probably
write an EEP.
But lets first discuss the topic here.

If I write the following module:
    -module(fun_test1).

    -export([start/0]).
    -export([hello/1]).

    start() ->
        F = make_fun(?MODULE, hello, 1),
        F("Andreas").

    hello(Name) ->
        io:format("Hello ~p\n", [Name]).

    make_fun(Module, Function, Arity) ->
        fun Module:Function/Arity.

I receive the following error message using R12-0:
    ./fun_test1.erl:14: syntax error before: Module
    ./fun_test1.erl:7: function make_fun/3 undefined
    error

I have now looked in to "Erlangs External Format and distribution protocol"
I think it would be plausible to transform:
    fun Module:Function/Arity.
To a value of tag 113.

It is doable with something like:
    make_fun(Module, Function, Arity)
        when
            is_atom(Module),
            is_atom(Function),
            Arity >= 0,
            Arity < 255 ->

        <<131, BinModule/binary>> = term_to_binary(Module),
        <<131, BinFunction/binary>> = term_to_binary(Function),
        <<131, BinArity/binary>> = term_to_binary(Arity),
        Bin = <<131, 113, BinModule/binary, BinFunction/binary,
BinArity/binary>>,
        binary_to_term(Bin).

I guess it is not possible to write a parse-transformer due to the
parser error.

The same problem applies to internal functions:
    -module(fun_test4).

    -export([start/0]).

    start() ->
        F = make_fun(hello, 1),
        F("Andreas").

    hello(Name) ->
        io:format("Hello ~p\n", [Name]).

    make_fun(Function, Arity) ->
        fun Function/Arity.

Where I receive the following error message using R12-0:
    ./fun_test4.erl:13: syntax error before: Function
    ./fun_test4.erl:6: function make_fun/2 undefined
    ./fun_test4.erl:9: Warning: function hello/1 is unused

But i leave to list decide if this also should apply to internal
functions exported as funs?


Kind regards
Andreas Hillqvist

2007/12/10, Christian S <>:
> On Dec 10, 2007 1:47 PM, Andreas Hillqvist <> wrote:
> > I am missing the ability to send Variables to "fun [xxx:]yyy/z".
> >
> > Something like:
> >     F = fun ExprF/0.
> >
> > And:
> >     F = fun ExprM:ExprF/0.
> >
>
> If you look at the document in the source that describes the external
> format you will see that this kind of fun (that just reference the fun to
> call by its name) already exist.
>
> If funs are bound to the offset and checksum into a module or if it is
> just referencing
> the names exposed by the external api has huge impact for code-switching.
> It feels like this is the area where you just have to be very
> experienced to know
> how and when to use funs without painting youself into a corner about
> how troublesome
> code switching will be.
>



More information about the erlang-questions mailing list