
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