[Haskell-cafe] Re: Proposal: register a package asprovidingseveralAPI versions

Claus Reinke claus.reinke at talk21.com
Wed Oct 17 08:38:43 EDT 2007

>> the idea was for the cabal file to specify a single provided api,
>> but to register that as sufficient for a list of dependency numbers.
>> so the package would implement the latest api, but could be used
>> by clients expecting either the old or the new api.
> I don't see how that could work.  If the old API is compatible with the new 
> API, then they might as well have the same version number, so you don't 
> need this.  The only way that two APIs can be completely compatible is if 
> they are identical.

if that is your definition of compatible, you can never throw any 
packages away, because they can never be subsumed by newer
versions of themself. alternatively, it would require perpetual 
updates of dependencies in package descriptions, which we'd 
like to avoid, right?

a few examples, of the top of my head:
- consider the base split in reverse: if functionality is only repackaged,
    the merged base would also provide for the previously separate
    sub-package apis (that suggests a separate 'provides:' field, though,    
    as merely listing version numbers wouldn't be sufficient)
- consider the base split itself: if there was a way for the base split
    authors to tell cabal that the collection of smaller packages can
    provide for clients of the the old big base, those clients would
    not run into trouble when the old big base is removed
- consider adding a new monad transformer to a monad transformer
    library, or a new regex variant to a regex library - surely the new 
    package version can still provide for clients of the old version
- consider various packages providing different implementations
    of an api, say edison's - surely any of the implementations will
    do for clients who depend only on the api, not on specifics

the reason this could work when updating packages is that packages 
written against the old api were not aware of the new features in the 
new api. when compiling a package against a dependency providing 
multiple versions, there should be a warning if the client does not 
refer to the newest version - but it would still build, and there'd be
a clear hint as to what needs to be changed.
> A client of an API can be tolerant to certain changes in the API, but that 
> is something that the client knows about, not the provider.  e.g. if the 
> client knows that they use explicit import lists everywhere, then they can 
> be tolerant of additions to the API, and can specify that in the dependency.

that is the very issue i'd like to see reversed. 

you're right the first time round: when the client is first written, 
it is the client's responsibility to specify a useable dependency 
version; but keeping the responsibility this way round causes 
nothing but trouble after the client has been released, if its 
dependencies develop faster than the client (in the current 
case, if a major change in base shakes the foundation all 
other packages were built on; a more typical example would
be: someone writes a useful package P, depending on X, Y, Z,
then leaves academia to hack web pages for a living, leaving
users and clients of P frustrated as X, Y, and Z move on).

so, i'd like to see two stages, before and after publishing:
1. author of client package specifies precise dependencies
2. users of client packages can continue using it unchanged
    even if its dependencies move on

one way to assure 2 is to keep all old package versions
around forever somewhere (we can't do a whole-web 
garbage collection, so we never know when there are 
no more pointers).

another way is to allow authors of package dependencies
to take on part of the burden, thereby helping to reduce
breakage and garbage for their clients. so the authors of 
mtl-9.0 could note that it still provides all the modules of 
earlier versions, so the package manage would only have 
to keep the latest version around, and clients of earlier 
versions would not notice any breakage.
> You'll get a type error - try it.  The big change in GHC 6.6 was to allow 
> this kind of construction to occur safely.  P-1:A.L is not the same type as 
> P-2:A.L, they don't unify.

i did (just before pressing send;-). the message (in 6.6.1) was 
of the kind 'A.L Integer' does not match 'A.L Integer'. i see 
you've now added both package and version to the error 
message - that should reduce the confusion. since package
sources may not be available, this is still not ideal, but i don't
see what to do about that.


More information about the Haskell-Cafe mailing list