Libraries and hierarchies

Iavor Diatchki diatchki@cse.ogi.edu
Fri, 01 Aug 2003 21:16:25 +0000


hello,

Simon Marlow wrote:
> ...
> THE PROBLEM
> -----------
> 
> Problem 1: Allocating names in the hierarchy
> 
> At the moment, we have a scheme of central registration (albeit
> informally on this list), along with a way for users to name libraries
> based on their email address (eg. User.Com.Microsoft.Simonmar.Foo).
> This is unsatisfactory, because (a) having a central registry for
> names is too cathedralish, and (b) it's inconvenient to use the
> email-address form because it gives rise to overly long module names.
> 
> Problem 2: Moving a module tree around
> 
> Suppose you have a tree of modules Control.Monad, Control.Monad.X,
> Control.Monad.Y etc, and you want to move them from Control to some
> other place Foo.Baz in the hierarchy, to give Foo.Baz.Monad,
> Foo.Baz.Monad.X, etc.  At the moment you have to visit every module
> and change its module header to give the correct absolute path name.
> 
> Problem 3: Long module names in imports
> 
> It's plain tiresome to have to write
> 	import User.Simon.Text.PrettyPrint.HughesPJ
> Long path names, repeated all over the source tree, are painful.
> They are particularly painful when you want to refer to another
> module in the same library -- then, if you decide to put the library
> somewhere else, you have to change all its internal imports.
i think you explained the problems quite nicely.


> A POSSIBLE SOLUTION
> ~~~~~~~~~~~~~~~~~~~
> The key idea is this: there is no longer a single global hierarchy of
> modules, but every site and every user has the means to populate their
> own module hierarchy as they see fit, with off-the-shelf and local
> libraries.
> 
> This means that when you install a package (a sub-hierarchy of modules),
> you get to choose where in the global hierarchy on your system it is
> rooted.  There would probably be a default, which you would most often
> go along with unless it clashes with another library on your system, in
> which case you might choose to site it somewhere else.  You can even
> choose to site it in several places in the tree.
> 
> If you want several versions of a library installed on your system, you
> can do that too, provided you site them at different places in the
> hierarchy.  If you install a new version of a library, just re-site the
> old one to a version-specific place, and install the new one.
> 
> eg. I install the GTK+HS library on my system.  By default, it sites
> itself under
> 
>       Graphics.UI.Gtk.*
>       Graphics.UI.Gtk.V0-15.*
> 
> and possibly additionally sites itself under a GUID-based root, or one
> based on an API hash:
> 
>       GUID_XXXXXXXX_XXXX_XXXX_XXXX_XXXXXXXXXXXX.*
> 
> When I install a new version of GTK+HS, say version 0.16, I can replace
> the existing Graphics.UI.Gtk with the new version, and I now have:
> 
>       Graphics.UI.Gtk.*  -- now refers to version 0.16
>       Graphics.UI.Gtk.V0-15.*
>       Graphics.UI.Gtk.V0-16.*
> 
> and two distinct GUID sites.
i think the problem is that when you write a piece of software you don't 
know that in the future things may change in bad ways, so you are likely 
to always use "Graphics.UI.Gtk".  Then later installing a new version of 
the library may break your program.  I guess, at this point you could go 
and replace all the imports with others explicitly mentioning the 
version number.  wouldn't it be more convinient, if one always refers to 
the library as "Graphics.UI.Gtk.*", but when compiling the program one 
gives the compiler a flag specifying which implementation of the package 
to use, e.g. something like:

ghc -package Gtk.V0-15 myprogram.hs or
ghc -package Gtk.V0-16 myprogram.hs


> ...
> 
> SOURCE CODE
> ~~~~~~~~~~~
> What about module names in the source code, and how are modules
> compiled?  Suppose I am compiling a package whose default site is
> Foo.Bar, and containing modules Foo.Bar.A.B, and Foo.Bar.A.C (assuming
> it is installed at the default site).  I put the source code in A/B.hs
> and A/C.hs, and the code would look like this:
> 
>     module A.B where
>     import A.C
> 
> The implementation must obey the following rule:
> 	When compiling a module belonging to a package, that package
> 	is temporarily grafted into the root of the module hierarchy.
> 
> This means that 'import A.C' will find the module A.C from the package
> being compiled.  If there is already a global module A.C, the package
> module "wins"; so the global module A.C is inaccessible.  (There could
> be some extra mechanism to get around this, if it seems important.)
> 
> Modules in other packages can be imported only by uttering their full
> path names in the global hierarchy (of the compiler that is compiling
> the package).
i don't quite understand this part. how is a module going to import 
modules from another package, if it does not know where these packages 
are going to be installed?  if i am writing a module M, which imports 
A.B.X.N which is module X.N from a package P that was installed at A.B,
doesn't that force everyone who is trying to use my package to install P 
at the same place: A.B?

bye
iavor



-- 
==================================================
| Iavor S. Diatchki, Ph.D. student               |
| Department of Computer Science and Engineering |
| School of OGI at OHSU                          |
| http://www.cse.ogi.edu/~diatchki               |
==================================================