cabal design

Duncan Coutts duncan.coutts at worcester.oxford.ac.uk
Tue Aug 16 12:10:40 EDT 2005


On Tue, 2005-08-16 at 16:31 +0100, Simon Peyton-Jones wrote:
> | First of all I want to thank Isaac Jones for his work on Cabal.
> | 
> | There are a few issues I would like to raise.
> 
> Seconded -- Isaac you are doing a great job.

Yes, indeed.

>   As are lots of other
> contributors.
> 
> One rather vexed question is the issue of whether a single program can
> contain two modules with the same name.  Currently that is absolutely
> ruled out, and as a result packages are fundamentally non-modular: every
> package must use a distinct space in the global namespace. 
> 
> Simon Marlow and I have gradually become convinced that we have to fix
> this, and the only sensible way to fix it is to relax the language
> design so that
> 
>        a module name must be unique within its package (only)
> 
> That means that module A.B.C could exist *both* in package P1 and in P2.
> And both packages could be linked into the same program.

I think it might be possible to have something slightly weaker. So that
modules which are used merely as an implementation detail may overlap
with modules of the same name in another package or the top level
program.

The thing that really annoys people is when some package they're using
internally uses some random utility module eg "C2HS.hs" then they cannot
use that same module name in their program. This is the case even when
the functions from that little utility module is not exposed in the
interface of the package.

Another nice example of this is when Cabal used to use a couple modules
from the util-1.0 package. These modules were not exposed through the
Cabal interface, they were purely an implementation detail and yet it
meant that no program that used any of the cabal libs could have a
GetOpt module (or one or tow other modules).

On the other hand, when a module re-exports entities from other modules
then those modules are in some sense exposed in the interface of the
module/package. In this case it is much more reasonable that the global
module namespace has been populated.

As an analogy from C, Gtk+ uses libpng as a private implementation
detail but it exposed the cairo api directly to user programs. Now I
believe that with the ELF linking format it is possible to set things up
such that if you link with Gtk+ (which links with libpng) you can still
use symbols in your top level program that are exported by libpng and
you will not get linker errors. What it does is link your program to Gtk
but not to libpng, even though Gtk+ itself links to libpng. So in effect
it draws a division in the collection of symbols in the program so that
the same name may appear in two places so long as they are not directly
linked. This only works because Gtk+ does not expose libpng in it's
interface.

Now on the other hand, unlike libpng which is a private dependency of
Gtk+, cairo is a public dependency of Gtk+. Programs which use Gtk+ can
directly use the cairo interface. So the ELF setup for the link between
cairo and Gtk+ is different to that between Gtk+ and libpng. So you
cannot reuse names from cairo without getting linker errors.

I suggest that we can use the same concept (and possibly the same tricks
with ELF linkage) for ghc's library packages. So we would need to
distinguish between public and private package dependencies. This can be
automatically checked by making sure no symbols from the private
dependency are re-exported. They must be used only in the
implementation.

So the point is that we would never need to qualify names with the
package they're from since it would never be possible to have both
instances of the same name in scope at the same place (or if you do,
it's because you directly imported it, in which case it's your fault).

So my point is that I think we can eliminate the vast majority of the
annoying module name clashes without having to go for a full "qualify
everything with it's package" approach. We just need a concept of which
module names a module or package exposes and make it possible to limit
the modules which become exposed to those from which things are
re-exported.

(There is a technical difficulty with this which is that things can
become re-exported due to inlining. It remains to be seen how the
difficulty might compare to some grafting solution, which I suspect is
not likely to play well with existing linker technology.)

Duncan



More information about the Libraries mailing list