Changes between Version 3 and Version 4 of Commentary/Packages/PackageCompatibilityProposal

Oct 25, 2007 9:40:35 AM (8 years ago)



  • Commentary/Packages/PackageCompatibilityProposal

    v3 v4  
    2828Furthermore, the package database cannot currently understand multiple packages compiled against different versions of dependencies.  One workaround is to have multiple package databases, but that's not too convenient.
    30 == 3. Provide older versions of base that re-export the new version ==
     30== 4. Allow packages to re-export modules ==
    32 To do..
     32Packages currently cannot re-export modules from other packages.  Well, that's not strictly true, it is possible to do this but it currently requires an extra package and two stub modules per module to be re-exported (see []).
    34 == 4. Do some kind of provides/requires interface in Cabal ==
     34This could be made easier.  Suppose you could write this:
    36 To do..
     37module Data.Maybe (module Old.Data.Maybe) where
     38import "base-2.0" Data.Maybe as Old.Data.Maybe
    38 == 5. Allow package overlaps ==
     41to construct a module called `Data.Maybe` that re-exports the module `Data.Maybe` from package `base-2.0`.  This extension to the import syntax was proposed in PackageImports.
     43Using this extension, we can construct packages that re-export modules using only one stub module per re-exported module, and Cabal could generate the stubs for us given a suitable addition to the `.cabal` file syntax.
     45Package re-exports are useful for
     47 * Constructing packages that are backwards-compatible with old packages by re-exporting parts of the new API.
     48 * Providing a single wrapper for choosing one of several underlying providers
     50== 4.1 Provide backwards-compatible versions of base ==
     52So using re-exports we can construct a backwards-compatible version of base (`base-2.0` that re-exports `base-3.0` and the other packages that were split from it).  We can do this for other packages that have changed, too.  This is good because:
     54 * Code is shared between the two versions of the package
     55 * Multiple versions of each package can coexist in the same program easily (unlike in proposal 2)
     57However, this approach runs into problems when types or classes, rather than just functions, change.  Suppose in `base-3.0` we changed a type somewhere; for example, we remove a constructor from the `Exception` type.  Now `base-2.0` has to provide the old `Exception` type.  It can do this, but the `Exception` type in `base-2.0` is now incompatible with the `Exception` type in `base-3.0`, so every function that refers to `Exception` must be copied into `base-2.0`.  At this point we start to need to recompile other packages against `base-2.0` too, and before long we're back in the state of proposal (2) above.
     59This approach therefore doesn't scale to API changes that include types and classes, but it can cope with changes to functions only.
     61== 4.2 Split base from underneath ==
     63This requires the re-exporting functionality described above.  When splitting base, we would create several new packages and additionally a backwards-compatibility wrapper called `base` that re-exports all of them.
     67 * Updates to existing packages are much easier (no configurations required)
     68 * Doesn't fall into the trap of trying to maintain a completely backwards-compatible version of the old API, as in 4.1
     72 * All packages still break when the base API changes (if they are using precise dependencies on base, which they should be)
     73 * Backwards compatibility cruft in the form of the `base` wrapper will be hard to get rid of; there's no
     74   incentive for packages to stop using it.  Perhaps we need a deprecation marker on packages.
     76== 5. Do some kind of provides/requires interface in Cabal ==
     78To do... someone please fill in a proposal here.
     80== 6. Distributions at the Hackage level ==
     82The idea here is to group packages into "distributions" in Hackage, with the property that all packages within a distribution are mutually compatible.  Todo... expand.
     84== 7. Allow package overlaps ==
    4086This is not a solution to the problem of splitting a package but helps in the case that we want to use a new package that provides an updated version of some modules in an existing package. An example of this is the bytestring and base package. The base-2.0 package included Data.ByteString but it was split off into a bytestring package and not included in base-3.0. At the moment ghc allows local .hs files to provide modules that can shadow modules from a package but does not packages to shadow each other.