Specifying dependencies on Haskell code
duncan.coutts at worc.ox.ac.uk
Sun Apr 20 16:22:56 EDT 2008
In the initial discussions on a common architecture for building
applications and libraries one of the goals was to reduce or eliminate
untracked dependencies. The aim being that you could reliably deploy a
package from one machine to another.
We settled on a fairly traditional model, where one specifies the names
and versions of packages of Haskell code.
An obvious alternative model is embodied in ghc --make and in autoconf
style systems where you look in the environment not for packages but
rather for specific modules or functions.
Both models have passionate advocates. There are of course advantages
and disadvantages to each. Both models seem to get implemented as
reactions having the other model inflicted on the author. For example
the current Cabal model of package names and versions was a reaction to
the perceived problem of untracked dependencies with the ghc --make
system. One could see implementations such as searchpath and franchise
as reactions in the opposite direction.
The advantages and disadvantages of specifying dependencies on module
names vs package names and versions are mostly inverses. Module name
clashes between packages are problematic with one system and not a
problem with the other. Moving modules between packages is not a problem
for one system and a massive pain for the other.
The fact is that both module name and package name + version are being
used as proxies to represent some vague combination of required Haskell
interface and implementation thereof. Sometimes people intend only to
specify an interface and sometimes people really want to specify
(partial) semantics (eg to require a version of something including some
bug fix / semantic change). In this situation the package version is
being used to specify an implementation as a proxy for semantics.
Neither are very good ways of identifying an interface or
implementation/semantics. Modules do move from one package to another
without fundamentally changing. Modules do change interface and
semantics without changing name. There is no guarantee about the
relationship between a package's version and its interface or semantics
though there are some conventions.
Another view would be to try and identify the requirements about
dependent code more accurately. For example to view modules as functors
and look at what interface they require of the modules they import. Then
we can say that they depend on any module that provides a superset of
that interface. It doesn't help with semantics of course. Dependencies
like these are not so compact and easy to write down.
I don't have any point here exactly, except that there is no obvious
solution. I guess I'd like to provoke a bit of a discussion on this,
though hopefully not just rehashing known issues. In particular if
people have any ideas about how we could improve either model to address
their weak points then that'd be well worth discussing.
For example the package versioning policy attempts to tighten the
relationship between a package version and changes in its interface and
semantics. It still does not help at all with modules moving between
More information about the Libraries