February 1999 Draft
JavaScript 2.0

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:

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.

Version Declarations

Version Names

A version name Version is one of the following:

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.

Declaration Syntax

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:

   [Visibilityversion Version [> VersionList;
   Version , ... , Version

A 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.

Version Ordering

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.

Version Ranges

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:

|  [Version1.. [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