[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'?

No.

That means that the following example is illegal:

-define(FOO, foo).
?FOO(?FOO) -> ?FUNCTION_NAME.

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'?
>
>     ?FUNCTION_NAME() -> ?FUNCTION_ARITY.

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
> "FUNCTION_NAME or FUNCTION_ARITY".

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

-- 
Björn Gustavsson, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list