February 1999 Draft
JavaScript 2.0
Versions
|
Thursday, February 18, 1999
As a package evolves over time it often becomes necessary to change its exported interface. Most of these changes involve adding symbols (global and class members), although occasionally a symbol may be deleted or renamed. In a monolithic environment where all JavaScript source code comes preassembled from the same source, this is not a problem. On the other hand, if packages are dynamically linked from several sources then versioning problems are likely to arise.
One of the most common avoidable problems is collision of symbols. Unless we solve this problem, an author of a library will not be able to add even one symbol in a future version of his library because that symbol could already be in use by some client or some other library that a client also links with. This problem occurs both in the global namespace and in the namespaces within classes from which clients are allowed to inherit.
There are several possible approaches to solving this problem:
com_netscape_length
method while MIT's objects used the edu_mit_length
method.The last approach appears to be the most desirable because it places the smallest burden on casual users of the language, who merely have to import the packages they use and supply the current version numbers in the import statements. A package author has to be careful not to disturb the set of visible prior-version symbols when releasing an updated package, but authors of dynamically linkable packages are assumed to be more sophisticated users of the language and could be supplied with tools to automatically check updated packages' consistency.
The versioning system in JavaScript 2.0 only affects exports of symbols. The concept of a version does not apply to a package's internal code; it is up to package developers to ensure that newer releases of their packages continue to behave compatibly with older ones.
A version describes the API of a package. A release refers to the entirety of a package, including its code. One release can export many versions of its API. A package developer should make sure that multiple releases of a package that export version V export exactly the same set of symbols in version V.
As an example, suppose that a developer wrote a sorting package P with functions sort
and merge
that called bubble sort in version 1. In the next release the developer adds a function called stablesort
and
includes it in version 2. In a subsequent release the developer changes the sort
algorithm to a quicksort that
calls stablesort
as a subroutine. That last release of the package might look like:
public version 1; public version 2 > 1; public function sort(funct compare, any[] array) any[] {...} public function merge(funct compare, any[] array1, any[] array2) any[] {...} public<2> function stablesort(funct compare, any[] array) any[] {...}
Suppose, further, that client C1 imports version 1 of P, client C2 simultaneously imports
version 2 of P, and a search for P yields the latest release described above. There would be only one
instance of P running -- the latest release. Both clients would get the same sort
and merge
functions, but only client C2 would see the stablesort
function. Both clients would get the quicksort
release of sort
. If client C1 defined its own stablesort
function, then that function
would not conflict with P's stablesort
; furthermore, P's sort
would still
refer to P's stablesort
in its internal subroutine call.
Had only the first release of P been available, client C2 would obtain an error because version 2
of P's API would not be available. Client C1 could run normally, although the sort
function
it calls would use bubble sort instead of the quicksort.
Note that the last release of P did not change the API so it did not need a new version. Of course, it could define a new version if for some reason it wanted clients to be able to demand the last release of P even though its API is the same as the second release.
A version name Version is one of the following:
double
number other than NaN.Two version names are said to be equal if their toString
representations are identical, so version names 2.0
and "2"
are identical but 2.0
and "2.0"
are not.
A package must declare every version it uses except version 1
, which is declared by default if not explicitly
declared. A version must be declared before its first use. A given version name may be declared only once per package. A package
declares a version name Version using the version declaration:
version
Version [>
VersionList] ;
,
... ,
VersionA version declaration cannot be nested inside a ClassDefinition's Block.
If Visibility is present, it must be either private
, package
,
or public
(without VersionsAndRenames). Unlike in other declarations,
the default is public
, which makes Version accessible by
other packages. A private
or package
Visibility
hides its Version from other packages; such a Version can be used
only by being included in the VersionList of another Version. Also
unlike other declarations, all Version declarations are global.
If the Version being declared is followed by a >
and
a VersionList, then the Version is said to be greater than
all of the Versions in the VersionList. We write v1 :>
v2 to indicate that v1 is greater than v2 and v1 :
v2 to indicate that either v1 and v2 are the same version or v1 :> v2.
Order is transitive, which means that if v1 :> v2 and v2 :> v3, then v1
:> v3. This order induces a partial order on the set of all versions. It is possible for two versions to be
unordered with respect to each other, in which case they are not equal and neither is greater than the other.
Order is predefined for versions whose names can be represented as double
numbers. For such versions v1
and v2, v1 :> v2 if and only if v1 is numerically greater than v2.
Additionally, every version except 0
is greater than version 0
. It is an error to define explicit
version containment relations that would violate this default order, directly or indirectly.
A VersionRange specifies a subset of all versions. This subset contains all versions that are both greater than or equal to a given Version1 and less than or equal to a given Version2. A VersionRange can have either of the following forms:
..
[Version2]The first form specifies the one-element set {Version}.
The second form specifies the set of all Versions v such that v :
Version1 and Version2
: v. If Version1
is omitted, 0
is assumed. If Version2 is omitted, the
condition Version2 :
v is dropped.
Waldemar Horwat Last modified Thursday, February 18, 1999 |