Revamping the module hierarchy

Ben Franksen ben.franksen at
Fri Jun 19 15:50:20 EDT 2009

wren ng thornton wrote:
> One of the nice things about the current arrangement is that
> the package namespace is orthogonal to the module namespace. These two
> concepts really are orthogonal, so it's good to keep them that way. When
> they get conflated into one, you end up with Java's import mechanism
> which is a complete wreck.


> I agree with Maurico that what we really need is to have the tools to be
> able to rearrange the tree at will. The Haskell language has no business
> dealing with the provenance of where modules come from--- and forcing
> modules to be named after their packages would make it do so. Currently,
> ghc-pkg (or whatever) handles the provenance of making sure that
> packages are visible to have their modules be loaded. As it stands, this
> provenance mechanism automatically roots all packages at the same place,
> but there's no reason it needs to. We just have to come up with the
> right DSL for scripting ghc-pkg (or equivalently, the right CLI) to be
> able to play around with the module namespace in a more intelligent way.
> For instance, let's assume we have:
>      > ghc-pkg describe libfoo-0.0.0
>      ...
>      exposed-modules: Data.Foo Control.Bar Control.Bar.Baz
>      ...
> Now, if we say:
>      ghc-pkg expose libfoo-0.0.0
> Then any Haskell programs can now load the modules mentioned above, by
> the names mentioned above. If instead we said something like:
>      ghc-pkg expose libfoo-0.0.0 at Zot
> Then Haskell programs would be able to load the modules by the names
> Zot.Data.Foo, Zot.Control.Bar, and Zot.Control.Bar.Baz instead. And if
> we wanted to rebase subtrees then we could say something like:
>      ghc-pkg expose libfoo-0.0.0:Control.Bar as Quux
> Which would make the modules Quux and Quux.Baz available for loading,
> and would effectively hide libfoo-0.0.0:Data.Foo from being loadable.

If I want to import a module I have to decide on /one/ module name. Since I
cannot know at which point in the hierarchy users might have exposed
modules from other packages, I must chose the default 'root' point. So,
this will not help library authors who want to e.g. import the 'same'
module from either mtl or transformers.

IMO it makes much more sense to let client packages decide from where in the
module hierarchy they want to import modules from another package, rather
than forcing users to decide this globally per installation.

Thus, grafting should not be done when exposing packages, but rather when
actually using them. Your examples above would become

  ghc -package libfoo-0.0.0 at Zot ...


  ghc -package libfoo-0.0.0:Control.Bar at Quux

This would also better play with the way cabal does things: cabal currently
ignores hidden/expoosed status of packages; instead it hides everything and
then explicitly 'imports' exact versions using the -package option. With a
few tweaks to the cabal file syntax, we could easily declare package 'mount
points' (even for subtrees) when declaring the dependent packages and this
would be tranformed to the ghc command line syntax above.


More information about the Libraries mailing list