[plt-scheme] On PLaneT packages and compatible upgrades

From: Robby Findler (robby at cs.uchicago.edu)
Date: Tue May 9 18:10:02 EDT 2006

Another possibility: we could force each import to have its own
(unique) prefix when imported into a module. In addition to avoiding
this problem, it seems like it could even help make people's programs
more readable, since imports would be identified at a glance.

Robby

At Tue, 9 May 2006 18:04:01 -0400, Richard Cobbe wrote:
> Evening, all.
> 
> I just discovered something that may affect other PLaneT package
> authors, so I'm sharing it here in the hopes that we can avoid some
> nasty package incompatibility issues.
> 
> PLaneT has the idea of a "compatible upgrade" to a package.  If one
> version is a compatible upgrade to another, older version, then the
> newer version should function as a drop-in replacement for the older.
> 
> We don't, however, provide a precise definition of "compatible
> upgrades," in part because it's a hard question.  But the conventional
> wisdom (as I understand it, at least) has pretty much always been that
> adding new functionality to a package is compatible, so long as you
> preserve existing behavior.
> 
> I discovered this afternoon that this isn't always true.  Consider the
> following situation:
> 
> * I write package foo.plt, which contains the following module:
> 
>     (module foo mzscheme
>       (define f (lambda (x) ...))
>       (provide f))
> 
>   I release this as version 1.0 of foo.plt.
> 
>   (In the real world, I'd provide f with a contract.  I'm leaving those
>   out for simplicity, since I don't think they're related to this problem.)
> 
> * Another party writes an application (or another PLaneT package;
>   doesn't matter) that uses foo.plt v1:
> 
>     (module bar mzscheme
> 
>        (require (planet "foo.ss" ("cobbe" "foo.plt" 1)))
> 
>        ... f ...  ;; f from foo.ss
> 
>        (define g (lambda (y) ...)))
> 
>   I (the author of foo.plt) am unaware of bar's existence.
> 
> * After bar has been written and is in use, I make some changes to
>   foo.plt, adding some new functionality:
> 
>     (module foo mzscheme
>        (define f (lambda (x) ...))    ;; same as in original version
>        (define g (lambda (a b) ...))
>        (provide f g))
> 
>   This (I think) is a compatible upgrade, so I release it as foo.plt v1.1.
> 
> * The other person's code no longer compiles.  Module bar fails because
>   it both defines and imports the identifier g.
> 
> So, the upshot is that the notion of a compatible upgrade is more subtle
> than we (or at least I) thought.
> 
> I'm not real sure how to solve this problem.  One strategy is that
> PLaneT clients should specify exactly what minor version number they
> want, as in
>     (require (planet "foo.ss" ("cobbe" "foo.plt" 1 (= 0))))
> That way, the application authors know that they'll always get the same
> version of the library -- they don't get an upgrade unless they
> explicitly ask for it, at which point they're presumably able to deal
> with the consequences.  The drawback, of course, is that PLaneT clients
> don't get automatic bugfixes.
> 
> Another possibility is to restrict the notion of a compatible interface
> to require that compatible upgrades may not add new exports.  The chief
> drawback here is that it requires the package authors to be very
> careful.  Even if everyone is well-intentioned, mistakes happen from
> time to time, and they can require a lot of effort to fix when they do.
> 
> Richard
> 
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme


Posted on the users mailing list.