Opened 5 years ago

Closed 5 years ago

#9375 closed feature request (fixed)

Support for module thinning/renaming on command line

Reported by: ezyang Owned by: ezyang
Priority: normal Milestone:
Component: Package system Version: 7.8.2
Keywords: backpack Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


In #8407, we added the capability for packages to reexport modules from other packages. This ticket is for the dual operation: during the compilation of a module, rather than being forced dump all of the exposed modules of package foo when I say -package foo, I should be able to selectively pick which modules I make visible (thinning) and rename them, if I like. For now, the proposed syntax is for all package flags, I can now write -package "foo (A as B, C)".

This feature has special implications for how the package database hiding/showing works. Currently, if I write -package foo-0.1, this will automatically go ahead and un-expose any other packages named foo that I may have loaded. But if I write -package foo-0.1 (Foo as Foo1) -package foo-0.2 (Foo as Foo2), I probably didn't actually want to hide the old instance of foo-0.1 when I exposed foo-0.2. More generally, rather than thinking of package configuration as flipping exposed/not-exposed bits on and off of an in-memory package database, we would rather think of it as setting up a mapping of module names to their implementations, and only reporting a conflict when there is an inconsistent module mapping.

Since this is a change of behavior, I propose two sets of semantics, controlled by a flag -backpack (but really, I mostly care about the second set). Flag naming can be negotiated.

In the absence of -backpack, thinning/renaming works by modifying the exposed/reexported module fields of the matched packages in the database. However, the old hiding behavior still applies, so this functionality would primarily be useful if two separate packages exported a module with the same name, and you still wanted to use both of them. So, the original example would not do what you want, but -package mtl (Control.Monad.Trans as MtlTrans) -package transformers (Control.Monad.Trans as TransformersTrans) would DTRT.

With the -backpack flag, no auto-hiding of packages occurs (this affects flags with thinning and renaming). Furthermore, the package database is cleared, as would be done with -hide-all-packages. We replace the old resolution algorithm with the new one, which processes each flag one-by-one while building a module mapping, picking a package which is consistent with the currently selected set of packages. This consistency is done by looking at the current module mapping and ensuring all of the modules the package would bring into scope are consistent with the modules we have already. Both example shown before would work; furthermore, -package foo -package foo would also continue to work, since foo's exports are consistent with itself. However, -package foo-0.1 -package foo-0.2 would be rejected (whereas now it is accepted.)

Change History (2)

comment:1 Changed 5 years ago by Edward Z. Yang <ezyang@…>

In 207875293fea07aa90efe215369629b657d1875a/ghc:

Thinning and renaming modules from packages on the command line.

This patch set adds support for extra syntax on -package and related
arguments which allow you to thin and rename modules from a package.
For example, this argument:

    -package "base (Data.Bool as Bam, Data.List)"

adds two more modules into scope, Bam and Data.List, without adding
any of base's other modules to scope.

These flags are additive: so, for example, saying:

    -hide-all-packages -package base -package "base (Data.Bool as Bam)"

will provide both the normal bindings for modules in base, as well as
the module Bam.

There is also a new debug flag -ddump-mod-map which prints the state
of the module mapping database.  H = hidden, E = exposed (so for
example EH says the module in question is exported, but in a hidden

Module suggestions have been minorly overhauled to work better with reexports:
if you have -package "base (Data.Bool as Bam)" and mispell Bam, GHC
will suggest "Did you mean Bam (defined via package flags to be
base:Data.Bool)"; and generally you will get more accurate information.
Also, fix a bug where we suggest the -package flag when we really need
the -package-key flag.

NB: The renaming afforded here does *not* affect what wired in
symbols GHC generates.  (But it does affect implicit prelude!)

ToDo: add 'hiding' functionality, to make it easier to support the alternative
prelude use-case.

ToDo: Cabal support

Signed-off-by: Edward Z. Yang <>

Test Plan: new tests and validate

Reviewers: simonpj, simonmar, hvr, austin

Subscribers: simonmar, relrod, ezyang, carter

Differential Revision:

GHC Trac Issues: #9375

comment:2 Changed 5 years ago by ezyang

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.