
Malcolm Wallace wrote:
Simon Marlow
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