Package "mounting" proposal

Simon Peyton-Jones simonpj at microsoft.com
Sun Jul 16 17:29:29 EDT 2006


| In particular, I propose to drop the assumption that Haskell modules
are
| closed entities but rather always consider them to be seen in the
context
| of a particular _package_. The package is now made responsible for
| assembling an appropriate (hierarchical) module namespace to which
imports
| in the packaged modules are taken to refer. To this end, the current
| 'depends:' entry in a package description would be replaced by a more
| general "mounting" construct, i.e. "mount package foo at Foo.Bar in
the
| module hierarchy". Optionally, as in [2], only a subtree of "foo"
could be
| selected, or only a specific version of "foo".

In fact what Sven describes is very close indeed to what Simon and I
propose, which is great.  Just as the imports of a module establish the
name-space for entities mentioned inside the module, so the Cabal file
(plus the installation setup) establishes the name-space for modules
specified in import statements (both unqualified 'import M' and
package-qualified 'import "gtk" M).  So the analogy is that
	the package dependencies of the Cabal file
		corresponds to
	the import statements of a module

We propose to use this analogy consistently:

** In a module you can mention an entity both unqualified 'f' (if that
is ambiguous) and qualified 'M.f' (to disambiguate); so in an import you
should be able to mention the module both unqualified 'import M' (if
that is umambiguous) and qualified 'import "gtk" M" (to disambiguate)

** In a module you can import another module 'qualified', so that its
entities MUST be referred to qualified (import qualified
M(f);....M.f...).  So, in the Cabal file, you should be able to say that
the exposed modules of a package are only available by qualified import
('import "gtk" M).

** In an import statement you can give an alias ('import M as Q").  So,
in a Cabal file, when giving the dependency on a package, you should be
able to specify an alias (needs new syntax).  For a start, when
depending on "gtk-4.2.3" you probably want to give it an alias "gtk", so
that the source code of the package mentions only "gtk" not the exact
version".

** In an export statement of a module you can say what is exported.
Cabal already has that, via the list of 'exposed' modules.

** In an 'import' statement you can bring into scope a subset of the
entities exported by a module.  Such a selective import would make
perfect sense at the package level too, but it's not so clear to us that
it's worth the bother.


How does this differ from what you propose?  Only in the following way:
instead of allowing a qualified import (i.e. one specifying a particular
package, or package alias), you build a single module name space, and
only allow unqualified imports. Instead of 
	import "gtk" M
you would establish "GTK." as the prefix for package "gtk", and then say
	import GTK.M.
This isn't a very big difference (which is good).  Personally, I like it
less, because it conflates *provenance* (where the module comes from)
with *purpose* (what it's for) in the single name.  Furthermore, the
qualified/unqualified analogy lets us import modules unqualified when
that's unambiguous, and qualified when it matters.  


Incidentally, everywhere I say "Cabal" I also mean "GHC's command line"
(or Hugs or nhc etc).  All Cabal does is invoke the compiler with
suitable arguments.

Simon


More information about the Libraries mailing list