Fixing "breaking packages"

Simon Marlow marlowsd at
Fri Mar 1 22:19:51 CET 2013

On 01/03/13 18:24, Max Bolingbroke wrote:
> On 1 March 2013 14:15, Ian Lynagh <ian at> wrote:
>> On Fri, Mar 01, 2013 at 03:02:41PM +0100, Jan Stolarek wrote:
>>> fixing things. I would like cabal to prevent such things from
>>> ever happening, the same way that
>>> Linux rpm/deb managers keep packages on the system in a consistent state.
>> There's one big difference here: rpm/dpkg are only used to install
>> things by the system administrator. But in the case of Cabal, a user
>> could install 'mypackage' (in their user package database) and the next
>> day the sysadmin could install a different instance of 'mypackage' in
>> the global database.
> I thought that "cabal install" should be viewed as installing an
> instance of the requested package by recompiling the whole transitive
> closure of dependencies from scratch, in a sort of NixOS-like way.
> Given this view, Cabal's reuse of already compiled and installed
> packages is purely an optimization that can prevent it from
> recompiling some things if it is absolutely certain that doing so is
> unnecessary. The problem then is just that Cabal is currently brokenly
> unable to handle multiple instances of an installed package with the
> same name and version.

Cabal comes under fire a lot, so I'd like to point out that it's not 
just Cabal that can't handle this right now, GHC can't either :-)

And various people have been thinking a lot about how to fix it, there 
was even a SoC project last year to tackle it.  The design notes are here:

> In this view, the existence of local and global
> databases is straightforward: packages should always be installed in
> the most-accessible DB to which you have write permissions (for
> maximum sharing) and should be sourced from whichever is convenient
> when they are required.

Right - when the DB is semantically just a cache, it doesn't matter 
whether stuff is installed in the global or local database. All those 
problems just go away.

> It seems to me that the ideal mental model for "cabal install
> mylibrary-1.1" is that it appends to a global mapping from package
> name to version which are essentially the packages that are available
> when you do "ghc -package mylibrary" and when using ghci. Cabals
> promise should be that it adds the requested package to the global
> mapping and then recompiles *everything* on your system as necessary
> in order to make it possible for every package in that global mapping
> to be imported simultaneously into a GHCi session.

The new library that you just asked to be installed might be 
incompatible with some other libraries that you asked to be installed, 
and yet you want to be able to use them both with GHCi (just not at the 
same time).  I don't think we should prevent the user from doing that.

So whether "cabal install foo-1.0" should store some state somewhere 
that says the user prefers foo-1.0 over other versions of foo is an 
interesting question.  (see the section "Simplistic Dependency 
Resolution" on the wiki page for some other thoughts on this).  One 
stance is that "cabal install foo-1.0" should do nothing except populate 
the cache; that is, it is semantically a no-op.  To have it modify some 
state breaks this nice no-op notion.


More information about the ghc-devs mailing list