[erlang-questions] lists:reverse/1 as a bui\lt-in function

Robert Baruch autophile@REDACTED
Tue Jan 23 23:47:02 CET 2007


On Jan 22, 2007, at 10:01 PM, Richard A. O'Keefe wrote:

> Neither.  The issue is not "which order to we write dotted names", but
> "where do we START from"?  Java chose absolute package names.  That is
> what is bad.  To take just one obvious example, suppose a group of
> classes/modules are developed by the Acme Widget company, so all those
> dotted names start out
>     nz.co.acme_widget.intercal.
> Then the Acme Widget company get taken over by Southern Doohicky, Inc,
> and now we *want* the names to be
>     au.com.southern_doohickey.intercal.
> Because package names are *absolute*, every dotted package name has to
> be changed.  But if dotted names were *relative* to the containing  
> class/
> module, only one name in the entire build would need changing.
> unnnecessarily

Ahhhh, now I understand the issue. It is certainly true that when the  
developer of some code decides to change their root package name, any  
application using that new code, as well as any code in the library  
itself, has to redo the package imports. I seem to recall the Java  
language had that happen to it at one point, but I can't remember  
what it was -- I think it was Swing that changed over to using the  
javax package.

I'm sure that caused the Swing developers some pain, and it cause me  
pain as well.


Anyway, yes, I can definitely see the advantage of a package name  
being relative.

Say I download someone's Erlang library. They decided to call it  
intercal, but in order to prevent a namespace clash with other  
applications that may also be called intercal, they put it in  
nz.co.acme_widget.intercal -- that is, this intercal is acme_widget's  
intercal, and not that other guy's intercal.

It would still be useful if I could import nz.co.acme_widget.* so  
that I could use intercal.foo.bar/1 -- that is, the bar function in  
the foo module in the intercal directory. The compiler would have to  
do a search through the import specs to locate a valid  
intercal.foo.bar/1, and if more than one were found, an error would  
be generated.

But now we get your problem again -- if they decide to change their  
name, I have to go through every file of mine and change import  
nz.co.acme_widget.* to au.com.southern_doohickey.*, and that would  
really suck if I had 100 files. Of course, that's what -include is  
for :)

So the modifications would be:

0. Imports are relative to some root. That root itself may be  
relative to some other root. If an import is relative to no root,  
then it is in the top-level namespace.

1. Name resolution searches through the imports, either matching a  
non-* import, or appending the name to a * import. If more than one  
import matches, an error is generated.

2. The name of a module is relative to some root. That root itself  
may be relative to some other root. If a module name is relative to  
no root, then it is in the top-level namespace.

Thus, suppose we had product intercal, with the following directory  
structure:

intercal/Foo.erl
intercal/Bar.erl
intercal/lower/Util.erl
intercal/lower/IO.erl

We would want Util and IO to be relative to .. (i.e. the directory  
above). We would further want Foo and Bar relative to .., and we  
would want intercal to be relative to nz.co.acme_widget. Note that we  
don't have to go through the bother of having a directory nz/co/ 
acme_widget, which I've always been annoyed at :)

Now, internal to the intercal product, Util.erl can now call Foo.baz/ 
1, because Util is relative to .., and therefore Foo.baz should be  
located in ../Foo.erl.

Furthermore, Util.erl could choose to -import(Foo). This means that  
it can now call baz/1, because the name resolver found a match in ../ 
Foo.baz/1.

This will also result in an error if there is a top-level Foo module  
with a baz/1 function, because then we don't know if you meant  
Foo.baz/1 or ../Foo.baz/1. The resolution is to specify  
either .Foo.baz (top-level) or nz.co.acme_widget.intercal.Foo.baz  
(fully qualified) -- or maybe even something that would allow you to  
specify a relative path.

It's a bit complex, now.

--Rob



More information about the erlang-questions mailing list