On the topic of cabal odisseys:

I think it would help to document (prominently) what Cabal fundamentally doesn't (try to) do, to avoid optimistic expectations (and hence the surprises when Cabal doesn't meet those expectations), and to point out the design choices behind many bug tickets (even if the choices are temporary
and driven by limited manpower). Such as

- cabal doesn't keep track of what it installs, hence

   - no uninstall
   - no application tracking
   - library tracking and information about installed
       library configurations only via ghc-pkg
   ..

- cabal's view of package interfaces is limited to explicitly
   provided package names and version numbers, hence

   - no guarantee that interface changes are reflected in
       version number differences
   - no detailed view of interfaces (types, functions, ..)
   - no reflection of build/configure options in versions
   - no reflection of dependency versions/configurations
       in dependent versions
   - no knowledge of whether dependencies get exposed
       in dependent package interfaces
   ..

This is just to demonstrate the kind of information I'd like
to see - Duncan&co know the real list, though they don't
seem to have it spelled out anywhere? So users see that
it works to say "cabal install" and build up their own often
optimistic picture of what (current) Cabal is supposed to
be able to do. It might even be useful to have a category
of "core-tickets" or such on the trac, to identify these as
work-package opportunities for hackathons, GSoC and the like, positively affecting many tickets at once.

On to the specific issue at hand:

2. cabal ought to allow using multiple versions of a single package in
more circumstances than it does now
..
2. This is a problem of information and optimisitic or pesimistic
assumptions. Technically there is no problem with typechecking or
linking in the presense of multiple versions of a package. If we have
a type Foo from package foo-1.0 then that is a different type to Foo
from package foo-1.1. GHC knows this.

So if for example a package uses regex or QC privately then other
parts of the same program (e.g. different libs) can also use different
versions of the same packages. There are other examples of course
where types from some common package get used in interfaces (e.g.
ByteString or Text). In these cases it is essential that the same
version of the package be used on both sides of the interface
otherwise we will get a type error because text-0.7:Data.Text.Text
does not unify with text-0.8:Data.Text.Text.

The problem for the package manager (i.e. cabal) is knowing which of
the two above scenarios apply for each dependency and thus whether
multiple versions of that dependency should be allowed or not.
Currently cabal does not have any information whatsoever to make that
distinction so we have to make the conservative assumption. If for
example we knew that particular dependencies were "private"
dependencies then we would have enough information to do a better job
in very many of the common examples.

My preference here is for adding a new field, build-depends-private
(or some such similar name) and to encourage packages to distinguish
between their public/visible dependencies and their private/invisible
deps.

This private/public distinction should be inferred, or at least be checked, not just stated. I don't know how GHC computes its ABI hashes - are they monolithic, or modular (so that the influence of dependencies, current package, current compiler, current option settings, could be extracted)? Even for monolithic ABI hashes, it might be possible to compute the package ABI hash a second time, setting the versions of all dependencies declared to be private to 0.0.0 and seeing if that makes a difference (if it does, the supposedly private dependency leaks into the package ABI, right?).

And secondly, how about making it possible for cabal files to express sharing constraints for versions of dependencies?

To begin with, there is currently no way to distinguish packages with different flag settings or dependency versions. If I write a package extended-base, adding the all-important functions car and cdr to an otherwise unchanged Data.List, that package will work with just about any version of base (until car and cdr appear in base:-), but the resulting packages may not be compatible, in spite of identical version numbers.

If it was possible to refer to those package parameters (build options and dependency versions), one could then add constraints
specifying which package parameters ought to match for a build
configuration to be acceptable.

Let us annotate package identifiers with their dependencies
where the current lack of dependency and sharing annotations means "I don't care how this was built". Then

   build-depends:  a, regex

means "I need a and regex, but I don't care whether a also uses
some version of regex", while

   build-depends: a, regex
   sharing: a(regex)==regex

would mean "I need any version of a and regex, as long as a depends on same the version of regex I depend on" (choose
any syntax that works). And

   build-depends: a, b
   sharing: a(text)==b(text)

would mean "I need any version of a and b, as long as they
both depend on the same version of text".

I can already think of situations where one might want more
complex constraints (e.g. "I want any version of base and mtl,
but either both have to be before the Either-move, or both
have to be after the move" - this part could be expressed
already, but there is currently no way to enforce this transitively, for dependencies, so if I depend on c, which depends on a new base, and on d, which depends on an old mtl, I'm out of luck, I think). Or: "never mix mtl and
its alternatives".

Of course, this scheme depends on whether it is possible
to reverse engineer the information about dependencies of
installed packages from ghc-pkg info or ABI hashes.. but
if the general idea is sound, perhaps that could be made
possible?

Just a suggestion,
Claus


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to