|
|
|
|
|
This page summarises our current proposal for packages in GHC. (See also [an extended proposal](ghc-package-namespaces) to make namespaces first-class, and [a proposal](package-mounting) for package mounting. The three proposals are mutually exclusive.)
|
|
This page summarises our current proposal for packages in GHC. (See also [an extended proposal](ghc-package-namespaces) to make namespaces first-class. The two proposals are mutually exclusive.)
|
|
|
|
|
|
## The problem
|
|
## The problem
|
|
|
|
|
... | @@ -14,32 +14,14 @@ There are two quite separate issues, addressed in "Question 1", "Question 2" bel |
... | @@ -14,32 +14,14 @@ There are two quite separate issues, addressed in "Question 1", "Question 2" bel |
|
|
|
|
|
Before we start, note that we take for granted the following
|
|
Before we start, note that we take for granted the following
|
|
|
|
|
|
- Each package has a globally-unique name, organised by some social process. This assumption is deeply built into Cabal, and lots of things would need to change if it wasn't met.
|
|
- **Each package has a globally-unique name**, organised by some social process. This assumption is deeply built into Cabal, and lots of things would need to change if it wasn't met.
|
|
|
|
|
|
- Module names describe *purpose* (what it's for, e.g. `Data.Bits`), whereas package names describe *provenance* (where it comes from, e.g. `"gtkhs"`). We should not mix these two up, and that is a good reason for not combining package and module names into a single grand name. One quite frequently wants to globally change provenance but not purpose (e.g. compile my program with a new version of package "foo"), without running through all the source files to change the import statements.
|
|
- **Module names describe *purpose* (what it's for, e.g. `Data.Bits`), whereas package names describe *provenance* (where it comes from, e.g. `"gtkhs"`)**. We should not mix these two up, and that is a good reason for not combining package and module names into a single grand name. One quite frequently wants to globally change provenance but not purpose (e.g. compile my program with a new version of package "foo"), without running through all the source files to change the import statements.
|
|
|
|
|
|
## Question 1: Can two different packages contain a module with the same module name?
|
|
- **New: a module name must be unique within its package (only)**. That is, a single program can use two modules with the same module name, provided they come from different packages. This is new in GHC 6.6. The old system (no two modules with the same name in the same program) meant that EVERY module in EVERY package written by ANYONE must have different module names. That's like saying that every function must have different local variables, and is a serious loss of modularity. Hence the change.
|
|
|
|
|
|
|
|
|
|
We now think that's unreasonable to answer 'no', because that means that EVERY module in EVERY package written by ANYONE must have different module names. That's like saying that every function must have different local variables, and is a serious loss of modularity. We suspect that this is something about which we can all agree.
|
|
For all this to work, GHC must incorporate the package name (and version) into the names of entities the package defines. That means that when compiling a module M you must say what package it is part of:
|
|
|
|
|
|
|
|
|
|
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. Suppose for the moment that A.B.C is not exposed by both P1 and P2. Then you would say simply:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
ghc --make Main -o app
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The authors of packages P1 and P2 didn't need to know about each other, and don't need to choose globally unique module names.
|
|
|
|
|
|
|
|
|
|
|
|
For this to work, GHC must incorporate the package name (and version) into the names of entities the package defines. That means that when compiling a module M you must say what package it is part of:
|
|
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
ghc -c -package-name P1 C.hs
|
|
ghc -c -package-name P1 C.hs
|
... | @@ -49,12 +31,18 @@ For this to work, GHC must incorporate the package name (and version) into the n |
... | @@ -49,12 +31,18 @@ For this to work, GHC must incorporate the package name (and version) into the n |
|
Then C.o will contain symbols like "`P1.A.B.C.f`" etc. In effect, the "original name" of a function `f` in module `M` of package `P` is `<P,M,f>`.
|
|
Then C.o will contain symbols like "`P1.A.B.C.f`" etc. In effect, the "original name" of a function `f` in module `M` of package `P` is `<P,M,f>`.
|
|
|
|
|
|
|
|
|
|
But what if two packages **expose** the same module A.B.C? That takes us to Question 2.
|
|
The remaining question is this: **When you say `import A.B.C`, from what package does A.B.C come?**. Three alternatives are under consideration:
|
|
|
|
|
|
## Question 2. When you say "import A.B.C", from what package does A.B.C come?
|
|
- Plan A (GHC's current story)
|
|
|
|
- Plan B: mention the package in the import
|
|
|
|
- Plan C: grafting. See [Frederik Eaton's proposal](package-mounting)
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
Here GHC already has a fairly elaborate scheme (perhaps too elaborate).
|
|
## Plan A: GHC's current story
|
|
|
|
|
|
|
|
|
|
|
|
GHC already has a fairly elaborate scheme (perhaps too elaborate; [documentation here](http://www.haskell.org/ghc/dist/current/docs/users_guide/packages.html))
|
|
|
|
|
|
- For a start, you may or may not have a package installed.
|
|
- For a start, you may or may not have a package installed.
|
|
- Even if you do, the package may or may not be exposed by default (reasoning: you may want old versions of package X to be installed, but not in scope by default).
|
|
- Even if you do, the package may or may not be exposed by default (reasoning: you may want old versions of package X to be installed, but not in scope by default).
|
... | @@ -66,10 +54,14 @@ When GHC incorporates package names in exported symbols, you will be able to exp |
... | @@ -66,10 +54,14 @@ When GHC incorporates package names in exported symbols, you will be able to exp |
|
- What if you wanted to import A.B.C from P1 and A.B.C from P2 into the *same* module?
|
|
- What if you wanted to import A.B.C from P1 and A.B.C from P2 into the *same* module?
|
|
- What if you want to only replace *parts* of P1 (e.g., you want to use an updated version of a module in `base`)?
|
|
- What if you want to only replace *parts* of P1 (e.g., you want to use an updated version of a module in `base`)?
|
|
- Compiling different modules with different flags in a way that affects the *semantics* (rather than, say, the optimisation level) seems undesirable.
|
|
- Compiling different modules with different flags in a way that affects the *semantics* (rather than, say, the optimisation level) seems undesirable.
|
|
- To support `--make` in this situation we'd need to allow `-package` flags in the per-module `OPTIONS` pragmas, which isn't currently supported. (`ghc --make` already gathers those options together for the link step.)
|
|
- To support `--make` in this situation we'd need to allow `-package` flags in the per-module `OPTIONS` pragmas, which isn't currently supported. (`ghc --make` already gathers those options together for the link step.) *This is not yet implemented, but it is close to being implemented.*
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
## Plan B: mention the package in the import
|
|
|
|
|
|
|
|
|
|
The obvious solution is to allow the programmer to specify the source package in the import line, something like this:
|
|
Another solution is to allow the programmer to specify the source package in the import line, something like this:
|
|
|
|
|
|
```wiki
|
|
```wiki
|
|
import A.B.C from "base" ( map, filter )
|
|
import A.B.C from "base" ( map, filter )
|
... | | ... | |