This EEP proposes two new macros called FUNCTION_NAME
and
FUNCTION_ARITY
that will return the name and arity, respectively, of
the current function.
The new predefined macro FUNCTION_NAME
expands to the name of the
current function (as an atom). The new predefined macro
FUNCTION_ARITY
expands to arity of the current function (as an
integer). Example:
a_function(_, _) ->
{?FUNCTION_NAME,?FUNCTION_ARITY}.
After preprocessing, the example will look like:
a_function(_, _) ->
{a_function,2}.
The preprocessor will expand all other macros before expanding
the FUNCTION_NAME
and FUNCTION_ARITY
macros. So if we have
this example:
-define(F, a_function).
?F(_, _) ->
{?FUNCTION_NAME,?FUNCTION_ARITY}.
the preprocessor will first expand it to:
a_function(_, _) ->
{?FUNCTION_NAME,?FUNCTION_ARITY}.
and then to:
a_function(_, _) ->
{a_function,2}.
The FUNCTION_NAME
and FUNCTION_ARITY
macros can be used in any
form that starts with an atom followed by a left parenthesis (when
all other macros have been expanded). The macros may be used even in
a function head. Thus, the following example is legal (albeit not
very useful):
a(?FUNCTION_NAME) -> ok.
It will be expanded to:
a(a) -> ok.
The FUNCTION_NAME
and FUNCTION_ARITY
macros will also work in the
presence of other macros in the function head. Example:
-define(__, _, _).
b(?FUNCTION_NAME, ?FUNCTION_ARITY, ?__) ->
ok.
This code will first be expanded to:
b(?FUNCTION_NAME, ?FUNCTION_ARITY, _, _) ->
ok.
and then to:
b(b, 4, _, _) ->
ok.
Using FUNCTION_NAME
or FUNCTION_ARITY
in an attribute will cause a
compilation error. Example:
-attr(?FUNCTION_NAME).
The error message will look like this:
example.erl:4: ?FUNCTION_NAME can only be used within a function
An invocation of FUNCTION_NAME
or FUNCTION_ARITY
must not begin a
form. Therefore, the following example is illegal:
?FUNCTION_NAME() -> ok.
The error message will look like this:
example.erl:4: ?FUNCTION_NAME must not begin a form
This EEP does not specify exactly how the FUNCTION_NAME
and
FUNCTION_ARITY
macros should be implemented, but it does impose some
requirements on the implementation:
The implementation must be efficient. In particular, there should
not be any noticeable slowdowns for modules that don’t use the
FUNCTION_NAME
or FUNCTION_ARITY
macros.
The expansion of FUNCTION_NAME
and FUNCTION_ARITY
must be done
by the epp
module. Postponing expansion of the macros to a later
compiler pass is not acceptable, as it could cause compatibility
issues with parse transforms and other tools that operate on the
abstract format.
-define(FUNCTION_STRING, atom_to_list(?FUNCTION_NAME) ++ "/" ++
integer_to_list(?FUNCTION_ARITY)).
test() ->
?FUNCTION_STRING.
The test/0
function will return "test/0"
. Note that the
BEAM compiler will evaluate constant expressions at compilation time;
thus, FUNCTION_STRING
will be turned into a string literal
during compilation.
c() ->
F = fun() -> ?FUNCTION_NAME end,
F().
The c/0
function will return c
.
The macros can be used when creating a fun that refers to the containing function:
self_ref(Data, Handler) ->
...
Handler(Data, fun ?FUNCTION_NAME/?FUNCTION_ARITY)
...
Many users have asked for some sort of macro that could return the
name of the current function, similar to FILE
, LINE
, and MODULE
.
For example: Why no ?FUNCTION macro.
The most common use case for a function name macro seems to be for
logging information to a log file. Possible workarounds include using
a parse transform, using process_info/2
, or generating and catching
an exception. Unless the application needs a parse transform for some
other reason, implementing a parse transform just to catch the name of
the current function is cumbersome. The other workarounds have
run-time penalties.
FUNCTION
macro? #
In order to minimize the pollution of the namespace of preprocessor
symbols, should there not be only a single FUNCTION
macro that would
return a tuple with the name and arity of the current function?
It would certainly be possible, but many common use cases would be somewhat cumbersome:
io:format("~p/~p: ~s\n", [element(1, ?FUNCTION),
element(2, ?FUNCTION),
Message])
Compare that to the more readable:
io:format("~p/~p: ~s\n", [?FUNCTION_NAME,
?FUNCTION_ARITY,
Message])
There are also contexts where element(1, ?FUNCTION)
or element(2,
?FUNCTION)
would be illegal, for example in function heads or after
the fun
keyword. The following example would fail to compile:
fun element(1, ?FUNCTION)/element(2, ?FUNCTION)
FUNCTION_STRING
myself? #
The most important reason is that there are two reasonable definitions:
-define(FUNCTION_STRING,
atom_to_list(?FUNCTION_NAME) ++ "/" ++
integer_to_list(?FUNCTION_ARITY)).
and
-define(FUNCTION_STRING,
?MODULE_STRING ++ ":" ++
atom_to_list(?FUNCTION_NAME) ++ "/" ++
integer_to_list(?FUNCTION_ARITY)).
There is no run-time penalty for defining FUNCTION_STRING
yourself, as the compiler will turn either definition of
FUNCTION_STRING
into a literal string during compilation.
Another reason is to avoid polluting the macro namespace with more predefined macros than strictly needed.
Historical note: MODULE_STRING
was added as an optimization in OTP
R7B, because at the time the compiler did not optimize constant
expressions as well as it does now.
FUNCTION_NAME
and FUNCTION_ARITY
allowed in function heads? #
I cannot see any practical use for the FUNCTION_NAME
and
FUNCTION_ARITY
macro in a function head. Only allowing them to be
used in function bodies would make sense. But consider this example:
f(a, _) ->
ok;
f(?FUNCTION_NAME, ?FUNCTION_ARITY) ->
ok.
To be able to reject invocations of FUNCTION_NAME
and
FUNCTION_ARITY
in clauses other than the first, the preprocessor
must basically be able to parse arbitrary Erlang code. The only
practical solution would be to use the existing parser in the
erl_parse
module. That would slow down the preprocessor without
providing any additional benefit.
Modules that define either FUNCTION_NAME
or FUNCTION_ARITY
will
fail to compile with a message similar to this:
example.erl:4: redefining predefined macro 'FUNCTION_NAME'
Similarly, attempting to define FUNCTION_NAME
or FUNCTION_ARITY
from the command line using -D
will also fail.
The reference implementation has essentially zero extra cost for
functions that do not use the FUNCTION_NAME
or FUNCTION_ARITY
macros. The preprocessor will only start scanning to determine the
name and arity of the current function when an invocation of either
FUNCTION_NAME
or FUNCTION_ARITY
has been seen. The scanning will
stop as soon as the right parenthesis at the end of the argument list
is found. The name and arity will be saved and reused if another of
invocation of FUNCTION_NAME
or FUNCTION_ARITY
is seen in the same
function definition.
The reference implementation can be fetched from Github like this:
git fetch git://github.com/bjorng/otp.git bjorn/function-macro
This document has been placed in the public domain.