[erlang-questions] clarify: variable as function name

Richard Carlsson richardc@REDACTED
Mon Dec 10 12:40:40 CET 2007

Lovei Laszlo wrote:
>    6.6 Function Calls
>    ExprF(Expr1,...,ExprN)
>    ExprM:ExprF(Expr1,...,ExprN)
>    ExprM should evaluate to a module name and ExprF to a function name
>    or a fun.
>    [...]
>    The module name can be omitted, if ExprF evaluates to the name of a
>    local function, an imported function, or an auto-imported BIF.
> This means that the following code is valid (F evaluates to a local
> function name):
>    f() -> ok.
>    g() -> F=f, F().
> In practice, this aborts with the reason badfun. The question is, which
> one is considered good: the manual, or the implementation?

The implementation, most definitely. The reference manual apparently
tries to give a very condensed description of function calls, and fails

- The two forms ExprF(Expr1,...,ExprN) and ExprM:ExprF(Expr1,...,ExprN)
need to be explained separately; they are too different.

- In the case of a call ExprF(Expr1,...,ExprN):

    * ExprF can be a constant atom (lexically), or otherwise it must
      be an expression which evaluates to a fun. Nothing else is
      possible. (In particular, no dynamically computed atoms.)
      ExprF usually needs parentheses around it if it is not an
      atom or a variable.

    * The handling of the constant atom thing is as follows: If the
      code contains <atom>(a1,...,aN), and <atom>/N is the name of a
      function imported (explicitly or automatically) from module M,
      then the call is rewritten as M:<atom>(a1,...,aN). Otherwise,
      the function <atom>/N must be a locally defined function, and
      the call is equivalent to (fun <atom>/N)(a1,...,aN).

    * This slight syntactic weirdness is due to the fact that lexically,
      Erlang uses atoms, not variables, to name functions. It's a
      remnant from Erlang's roots in Prolog. It gets strange sometimes
      but we can live with it.

- In the case of a remote call ExprM:ExprF(Expr1,...,ExprN):

    * ExprF must evaluate to an atom; it cannot be a fun.

    * ExprM must evaluate to an atom (or, inofficially, to a value that
      represents an instance of an abstract module).

    * It does not matter if ExprM and ExprF are lexically atoms or not.
      However, the compiler can generate a bit more efficient code
      if both ExprM and ExprF are known at compile time.


More information about the erlang-questions mailing list