[erlang-questions] EEP 45: New macros for function name and arity
Richard A. O'Keefe
Wed Nov 11 01:52:56 CET 2015
It's looking good, but there is something I do not
"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.
?FOO (?FOO) -> ?FOO.
Is this a 'form that starts with an atom followed
by a left parenthesis'?
(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.
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.
I am not suggesting that this is the way that this
feature *should* be implemented, but that it took me
a fair bit of mental effort to come up with a model
for how this *could* work. And that suggests to me
that something *like* this model should be part of
the user documentation for this feature.
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.
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
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".
Returning to FUNCTION_STRING, since
bar(?MODULE_STRING) -> foo.
foo(atom_to_list(?MODULE)) -> bar.
does not, it appears that ?MODULE_STRING is not
redundant, and that means that ?FUNCTION_STRING
would not be redundant either. Mind you, using
?MODULE_STRING in a function head is much more
plausible than using ?FUNCTION_STRING.
Alternatively, the Erlang compiler could evaluate
atom_to_list(Atom) and integer_to_list(Integer)
More information about the erlang-questions