[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
miserably.
- 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.
/Richard
More information about the erlang-questions
mailing list