[plt-scheme] On PLaneT packages and compatible upgrades
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