Re-exporting namespaces

Simon Marlow simonmarhaskell at gmail.com
Mon Jul 10 07:36:17 EDT 2006


Malcolm Wallace wrote:
> Simon Marlow <simonmarhaskell at gmail.com> wrote:
> 
>>So I don't like this idea of re-exporting namespaces.  Here's why.
>>
>>When I see 'import M', I have to search not only the filesystem, but 
>>also for possible namespaces re-exported by *all* the other import 
>>declarations in the file, which means I have to understand all those 
>>other import declarations, and the process is recursive.
> 
> True.  But I don't see how it is much different from ordinary imports:
> if an entity e is used in the source text, but not defined there, you
> must search the modules that are imported to see where e was defined.

The big difference is that under your proposal it affects finding the modules in 
the first place, not just resolving identifiers in the source code.  So hmake is 
affected, likewise the dependency phase of ghc --make.

Consider that at the moment, an import declaration can be considered completely 
independently of the rest of the module.  Imports do not affect each other. 
This is true now (note that 'as' doesn't affect other imports), and in the other 
packages proposals.  Under your proposal, all imports have to be considered 
together to determine whether any are ambiguous.  We can't do Hugs-style 
one-at-a-time import chasing, for example.  It's also inconsistent with the 
current behaviour of 'as'.

In hmake you have the option of trying to do a complete job, which is hard, or 
just ignoring imports that you can't resolve on the grounds that they might be 
namespace re-exports.  The latter defers some errors until compile time.


>>I believe there should be a clean separation between
>>   - constructing the global module namespace, and
>>   - interpreting the source code of a module
> 
> OK, but that is in direct conflict with the original proposal (to
> specify a package alongside a module import), which abandons the idea of
> a "global" module namespace!

No - there's still a global module namespace, but it is indexed by (package 
name, module name) pairs.

Perhaps I shouldn't have used the word "global".  Imagine I'd left it out. 
Constructing the module namespace is something that can be done by a simple 
dependency analysis if the modules in a program - this is done right now by ghc 
--make and hmake.  It only requires parsing source modules to extract the module 
name and the imported modules, nothing more.


>>that is, mapping an import declaration to a module should require 
>>nothing more than searching the filesystem and package database.  This
>>is true now, and I think we should ensure it remains true, for the 
>>benefit of tool and language implementors.
> 
> At the moment, the compiler must search the filesystem, package
> database, and *interface files* (for imports/re-exports).

No - note that I said "mapping an import declaration to a module".  Not an 
entity, just a module (to be concrete: which M.hs or M.hi does 'import M' refer 
to?).  This is simple right now; with your proposal it gets a lot harder.

I accept that the GhcPackages proposal has a serious shortcoming that your 
proposal addresses, namely that there's no way to name a package in just one 
place if you're using package-qualified imports.  I don't yet know of a good way 
to fix this, but I'm fairly sure that generalising the module system with 
namespaces is not a good power/weight tradeoff.  Packages are supposed to be 
simple things, I can't imagine explaining, let alone completely specifying this 
system.

I've started working on GHC's package system, and the main technological 
difference - changing the identity of a module to be a (package,module) pair - 
is quite straightforward.  From here, it'll be trivial to allow an import 
declaration to specify a package.  Grafting via command-line options would be a 
bit more complexity, but not much: the compiler already builds a module name to 
(package,module) mapping from the package database, and grafting just adds more 
entries to this mapping.  Note that this is done before reading any source code.

Things get a bit more tricky if grafting declarations can be in the source code, 
or {-# OPTIONS #-} pragmas: the modue mapping has to be built for each module, 
before reading import declarations (that means the dependency analyser has to do 
it, too).  But, if import declarations themselves could augment the module 
namespace, and we have to store this information in .hi files... that's a whole 
lot more complexity.  I think it's a step too far.

Cheers,
	Simon


More information about the Libraries mailing list