(Complete) range dependencies back in the game?

Jesse Glick jesse.glick at oracle.com
Fri Jan 13 05:34:23 PST 2012


On 01/08/2012 11:44 AM, Jaroslav Tulach wrote:
> http://wiki.apidesign.org/wiki/RangeDependenciesAnalysed

"It does not make much sense to have higher upper bound of dependency on C higher than any existing upper bound on C among reused libraries (thus s <= q)" - I disagree 
that this does not make sense.

Let us say that C has both an API and an SPI; the API is kept quite stable but the SPI is frequently rewritten (and the handful of implementations are expected to keep 
up). So pretend C is DOM, and API clients normally use ranges like [1.2,2) ("DOM 2 or any foreseeable compatible release") whereas SPI implementations normally use ranges 
like [1.2,1.3) ("DOM 2 but not 3").

Now pretend B is a library for XML persistence of Java objects, and during one serialization mode it creates flyweight org.w3c.dom.Document's. Versions 1.0 through 1.3, 
written back when DOM 2 ruled the land, declares [1.2,1.3); version 1.4 and later implement DOM 3 so declare [1.3,1.4) but are otherwise fully compatible for callers.

Finally say A is an application which uses XML serialization for some preferences storage, and also uses DOM quite independently for dealing with REST clients. So it 
would like to declare B@[1.0,2) and C@[1.2,2): it uses only the basic initial serialization API, and can work with any known DOM release.

The fact that B at 1.0 is incompatible with C at 1.3 does not trouble the author of A; the app would work fine with B at 1.5 and C at 1.3 as well. If the compiler silently converted 
the dep on C@[1.2,2) to C@[1.2,1.3), it would effectively mean that B at 1.4 could not be used even if it had numerous bug fixes, which is generally not what you want. It 
could instead just reject A's attempted expression of what its actual dependency ranges are, with some sort of error message TBD, and the author of A would (after some 
trial and error) eventually give up on supporting older libraries and request B@[1.4,2) and C[1.3,2).

This switch would be rather artificial: the originally attempted dependency declaration was logically sound, and a module system using a SAT solver would not have 
difficulty linking A with either newer or older libraries according to what is available. (An organization which decided it hated the DOM 3 license might forbid it from 
being installed, in which case you would like to be able to run A with B at 1.3 and C at 1.2.)

Indeed if A does not use XML namespaces in its REST API, it could as well declare C@[1.1,2) even knowing that current versions of B require at least C at 1.2; a future 
version of B might stop needing to implement DOM and (if it did not use namespaces either) might declare C@[1.1,2), in which case B at 1.7 C at 1.1 would be a valid 
configuration too. Obviously this is a less likely scenario, but it shows that "[t]his definition seems to make sense from the point of lower bound" is not so obvious either.


On this topic, I think the definition of complete repository is unnecessarily strict; there is no reason apparent to me why [r,s) must be a subrange of [p,q), though it 
does at least need to overlap (and probably a version of C in that intersection must actually be present in the repo). Where in the proof is the assumption of subranges 
used? You only check whether cr is empty, which it would be in the attempted conversion to 3-SAT. It seems that A could express any dependency on C it likes, and trying 
to compile A would either work or not work, according to whether its dep on C has at least some overlap with that of the earliest versions of its other dependencies.


By the way, you do not really discuss selecting a configuration at install time in a complete repository. [1] does not seem to apply to arbitrary range dependencies. 
Probably you can start with a configuration using the lower bounds of all dependencies as determined during compilation, then iteratively try raising the version of each 
module individually so long as doing so continues to result in a valid configuration - i.e. pick a locally maximal configuration. This is polynomial.


[1] http://wiki.apidesign.org/wiki/LibraryWithoutImplicitExportIsPolynomial#Merge_of_Configurations



More information about the jigsaw-dev mailing list