[erlang-questions] EEP 45: New macros for function name and arity

Björn Gustavsson bjorn@REDACTED
Wed Nov 11 07:24:58 CET 2015

On Wed, Nov 11, 2015 at 1:52 AM, Richard A. O'Keefe <ok@REDACTED> wrote:
> It's looking good, but there is something I do not
> understand.
> "The FUNCTION_NAME and FUNCTION_ARITY macros can be used in   any form that starts with an atom followed by a left parenthesis."
> (1) Does this mean *before* or *after* macro expansion.
>     -define(FOO, foo).
>     ?FOO (?FOO) -> ?FOO.

Before macro expansion, as currently implemented.

>     Is this a 'form that starts with an atom followed
>     by a left parenthesis'?


That means that the following example is illegal:

-define(FOO, foo).

The error message will be "?FUNCTION_NAME can only
be used within a function".

That is unfortunate. The preprocessor could
do macro expansion before looking for an
atom and a left parenthesis, but then we
would have to think carefully about (2).

> (2) The expansion of ?FUNCTION_NAME is an atom.
>     So is *this* a 'form that starts with an atom
>     followed by a left parenthesis'?

No. Currently, the error message would be
"?FUNCTION_NAME can only be used within a function".

Clearly, this example must be illegal, but
the error message is not very good.

I will have to think about this.

> I think I have finally understood how ?FUNCTION_NAME
> and ?FUNCTION_ARITY can work in a function head.  The
> trick is that when you first go through, you don't
> know _which_ atom and integer they are, but you do
> know _that_ they are an atom and an integer and cannot
> possibly be hiding any commas.  So it can be done in
> two rounds.  First a round of macro expansion as at
> present, but passing ?FUNCTION_NAME and ?FUNCTION_ARITY
> along as literals, then a round where they are replaced
> by their values.

Yes, that it is how I have implemented it.

I only do two rounds if a macro invocation is
actually found in the function head.

> The ?FUNCTION_STRING example is all very well, but as
> a bear of very little brain I could use a reminder of
> whether this is expected to work in a function head
> or not.  Given that
> bar("test"++"/"++"3") -> foo.
> works it is certainly surprising that
> foo(atom_to_list(test)++"/"++integer_to_list(3)) -> bar.
> doesn't.  This suggests to me that ?FUNCTION_STRING
> *won't* work in a function head, and the EEP should
> probably say so.

Correct. It won't. Operators are allowed in
patterns, but not BIF calls.

> I don't think there is any *need* for ?FUNCTION_STRING
> to work in a function head, it's just that since
> ?FUNCTION_NAME and ?FUNCTION_ARITY do, it deserves
> explicit mention.

OK. I'll mention it.

> The FUNCTION_STRING example is followed by a section
> asking why FUNCTION_STRING doesn't exist.
> "To be able to reject invocations of FUNCTION in clauses"
> looks like an unfinished edit; "FUNCTION" should be

Yes, I missed that one.


> Alternatively, the Erlang compiler could evaluate
> atom_to_list(Atom) and integer_to_list(Integer)
> in patterns...

That would be the subject of a separate EEP.


Björn Gustavsson, Erlang/OTP, Ericsson AB

More information about the erlang-questions mailing list