[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