[erlang-questions] Package Support/Use
Tue Oct 31 13:36:39 CET 2006
Thomas Lindgren wrote:
> 1. The semantics of packages and module names is dodgy
> (as far as I know).
Seems I never answered that last post of yours in that thread.
I'll try to do so now. Your example was:
f1() -> m:f(X).
f2() -> Mod = m, Mod:f(X).
where f1() and f2() do not do the same thing if the module
is in a package (as it is in this example): f1() calls
'foo.m':'f'(X) (the name is expanded in the call context)
while f2() calls 'm':'f'(X).
This does break referential transparency, i admit. What you
need to keep in mind is that if you do move the module name out
of the call context and into a variable, you must make sure
to use its full name. This was the (minor, I think) price paid
for making the package system work.
The documentation for the package system makes a clear
distinction between the unqualified module name and the
full module name. In Erlang code that does not use packages,
these are always the same, and the ?MODULE macro will always
expand to the full name. Furthermore, the M:F(X) notation as
well as the apply*/N and spawn*/N built-in functions always use
the full module name. So, if you have code in some (unpackaged)
module bar that uses a *full* module name "Mod = m", then that
m will still refer to the same module even if the containing
module bar is renamed to foo.bar. Basically, there is never any
run-time expansion of module names, because the necessary context
is in general missing if you pass an unexpanded name as an atom.
Hence, all module names being passed around are always full names,
which means that e.g. an old module such as gen_server, written
entirely without any knowledge about such things as packages,
can work with a packaged callback module whose full name might
be something like foo.bar.my_server.
But what I think you were looking for, was to have a way of
getting the full name of a "local" module as an atom, given
only its unqualified name. In fact, I had experimentally included
a pseudo-BIF 'expanded(Atom)' (or some such name) - expanded at
compile time, if possible. But at the time, I was a bit afraid to
add a new predefined name and was not sure how useful it would turn
out to be, so it was never included in the system. Mea culpa, I guess.
But it is not too late to add such an operator now. Its semantics
could easily be defined in terms of the full name of the containing
module, i.e., the value of ?MODULE, and a couple of the name-
manipulation functions in the 'packages' kernel module. Making the
compiler recognize and expand it statically when possible, is quite
simple, and can be done regardless of whether the function is
automatically imported or not. Any name suggestions?
PS. Now that I look at it, none of the exported functions in the
'packages' module are documented. This should be fixed.
More information about the erlang-questions