By defining '$handle_undefined_function'/2 in a module, that module can
catch and handle wrong-arity calls to the module's top-level functions.
(The standard error_handler is also involved.)
Unfortunately, this behaviour is limited to top-level functions, either
M:F(...) calls, or Fun(...) calls where Fun = fun M:F/N.
For local Funs, the first issue is that beam_emu.c:call_fun() states:
* There is a module loaded, but obviously the fun is not
* defined in it. We must not call the error_handler
* (or we will get into an infinite loop).
and then skips calling the error_handler.
What is this infinite loop, and could we do something to prevent it?
The second issue is that even if beam_emu routes a wrong-arity Fun(...)
call via the error_handler to a handler in the Fun's module, that handler
has no sane way to identify the Fun. In the erlang:fun_info/ output,
the index/uniq values are of no use (that I can see), and the name is
"generated by the compiler, and is only of informational use".
What I'd really want is a way to attach my own attribute to a fun
expression, and have erlang:fun_info/ return it.
Being able to handle wrong-arity calls to local Funs would simplify
compiling languages like Scheme to the BEAM. Scheme has both fixed-arity
and variable-arity functions, and since it's dynamically typed you don't
know at a call site what kind of function you're calling.