> > ...can there be a general solution to that that will work in a way
> > that doesn't discourage people from making more modules? I don't
> > think that there's a sensible way for that -- even if you take an idea
> > world where people specify full contracts, you'll have to do some
> > analysis for the actual functionality used to know when a new version
> > is incompatible. It's pretty common to find some higher level stable
> > interface, and then some lower-level stuff that was exposed for some
> > reason which is much less stable, or new functionality which you're
> > not sure about.
>> I hadn't thought about this problem before. Thanks for bringing it up.
>> It seems there are a few different ways the system could handle this.
> First, we could take it as evidence that contracts aren't a good match for
> the compatiblity problem. Second, we could agree that some contracts are
> useful and others are not, and allow library authors to specify some
> portion of their interfaces and ignore those portions when we perform
> checks (possibly along with warning users when they're upgrading a package
> whose unstable interface is being used by another package or something
> along those lines). Third, we could decide that your use of interfaces is
> incompatible with an automatic-upgrade system and require that library
> authors not have unstable interfaces if they want to make use of the
> compatibility features of CSPAN.
>> Of those, the third option appeals to me the least and the second appeals
> to me the most, but I'm worried that I'm just falling into trap of
> throwing new features at every problem. It'd be better to make a system in
> which some reasonable design pattern gave you this capacity for free.
>> Does anyone see a better solution?
>> -jacob
>
I'm not too fond of the use of contracts for compatibility, at least not
unless there is a way to override the behavior. In addition to the weakness
Eli pointed out, I may wish to provide more precise contracts in later
versions of a library. For example,
fake-tcp-listen : nat -> fake-listener
consumes a network port and returns something like a tcp-listener.
Actually, the port number must be > 1024 and < 2^whatever, so I
refine my contract in the next version. Clients that called the
code with (fact 200) as the network port will now be blamed instead
of the library. This is good for assigning blame. It's not good
for upgrading. The original program didn't work anyway unless the
argument was between 1024 and 2^whatever anyway. All I did was
move a check into a contract.
I would rather see
- each module come with a test suite
It could be (lambda () 'I-pass) for careless folks.
- When module A requires module B, updating the link from A to B to
use a new version of B is okay iff A's testsuite still passes.
Multiple require links may need to upgrade simultaniously.
Authors can recommend that their links be upgraded by upgrading
package A to refer to new versions required libraries.
I guess this would not work well if people don't submit testsuites.
I do think it would be good to be able to roll back after an "up"grade.
I think everyone agrees already, but having multiple versions of a library
is a necessity. An upgrade that removes an experimental feature may be
fine for most users, but not for one or two. This is why the suitability
of replacing B with B' should depend on the relationship between A and B'
more than on B and B'.
One problem is that a packages with N imports with M more recent versions
of each import has M^N possible upgrades. Maybe the best bets to try
are eitherh no upgrades, all new upgrades, or all upgrades that are
supposed to be compatible or have contracts matching or some heuristic.
I still want to run the test suite of A even if B' and B have mathching
contracts and are supposed to be compatible.
Looking forward to the new PLaneT,
Paul