From: Shiro Kawai
Date: Wed, 13 Jun 2007 22:18:38 -1000 (HST)
Subject: [Formal] Version reference syntax is overly complex.
Submitter: Shiro Kawai
Type of issues: Simplification
Priority: Minor
Component: Libraries (section 6.1)
Version of the report: 5.94
Short summary: Version reference syntax is overly complex.
Full description of the issue
----------------------------
The distinction of and
in the import clause syntax makes it unintuitive, especially
since the keyword 'and', 'or', and 'not' can appear in both rules.
For example, it takes some mental training to see the following
import clauses are invalid:
(import (foo (or 1 2)))
(import (foo (>= 2)))
while the latter two are valid and effectively have the same
meanings:
(import (foo (or (1) (2))))
(import (foo ((or 1 2))))
It is also easy to write a syntactically valid version reference
which doesn't have much use in practice:
(import (foo (1 (>= 1) 4)))
(import (foo (1 (or 2 3) 1)))
(import (foo (1 (not 2) 2)))
Basically, using level and/or/not/>=/<=
keywords are only useful when it appears at the last position
in . On the other hand, whenever more than
one sub-version is involved in the operation, we have to fall
back to level operation:
;; any version after 1.0.1.1
(import (foo (and (1 0 1 (>= 1))
(1 0 (>= 2))
(1 (>= 1))
(>= 2))))
;; version 2.3.x were x >= 2, except version 2.3.2.2
(import (foo (and (2 3 (>= 2))
(not (2 3 2 2)))))
This made me suspicious of the value of having
syntax.
I propose two alternative ideas.
Suggested alternative #1
------------------------
Change the syntax to the following:
: ()
| ( . )
| (or ...)
| (and ...)
| (not . )
| (>= . )
| (<= . )
Semantics:
A Vr matches a V when:
- Vr is ()
- V is () and Vr is (0 ...)
- (car Vr) is , and (eqv? (car Vr) (car V)),
and (cdr Vr) matches (cdr V).
- (car Vr) is or, and either one of s in (cdr Vr)
matches V.
- (car Vr) is and, and all of s in (cdr Vr) in Vr
matches V.
- (car Vr) is not, and (cdr Vr) doesn't match V.
- (car Vr) is >=, and V is greater than or equal to (cdr Vr).
- (car Vr) is <=, and V is less than or equal to (cdr Vr).
Where the comparison of two versions V1 and V2 are defined as follows.
- If the lengths of V1 and V2 differ, append as many 0's to the
the shorter one as to make the both versions with the same length.
- If both V1 and V2 is (), they are the same.
- If (car V1) < (car V2), V1 is less than V2.
- If (car V1) > (car V2), V1 is greater than V2.
- If (car V1) = (car V2), compare (cdr V1) and (cdr V2).
Examples:
;; version 1.1.2.1 or 1.1.3.2
(1 1 or (2 1) (3 2))
(1 1 . (or (2 1) (3 2)))
;; any version after 1.0.1.1 (e.g. 1.0.1.2, 1.0.2, 1.1, or 2.1)
(>= 1 0 1 1)
;; version 1.2.x where x >= 3
(1 2 >= 3)
(1 2 . (>= 3))
;; version 2.3.x were x >= 2, except version 2.3.2.2
(2 3 and (>= 2)
(not 2 2)))
(2 3 . (and (>= 2)
(not 2 2)))
;; for version 1 series, version 1.2.1 or later
;; for version 2 series, any version.
(or (1 >= 2 1)
(2))
(or (1 . (>= 2 1))
(2))
;; version 2.3 but not 2.3.1 or later. 2.3.0.1 is OK.
(2 3 not >= 1)
(2 3 . (not >= 1))
Note 1: The version comparison rule makes version (2 3) and (2 3 0)
equal. I think it is acceptable.
Note 2: This rule doesn't restrict to be negative.
It is useful in practice, to represent "pre-release" or
"release-candidate" version, though I don't think r6rs to
consider such a case (keeping it to implementation-specific extension).
Suggested alternative #2
------------------------
Drop the whole library versioning idea from r6rs.
I do recognize the importance of library versioning; however,
the current R6RS spec seems off-balance. It specifies
the version reference very thoroughly that will cover
complicated cases which will be used rarely; on the other
hand, it doesn't specify an important feature in practice,
by which the library user can switch code based on which
version of library is actually imported---it is absolutely
necessary if the library has changed API among versions.
Another unresolved issue is the need to make different versions
coexist in one program, as Pinku Surana pointed in
<001c01c7adcf$feb886d0$6800a8c0 at Spike>.
I think we can put off the whole versioning issue into SRFI,
until we have enough r6rs-compatible libraries and find out
what will work best in the practical situation.
RESPONSE:
While the suggested change is reasonable, it was too late in the
process to be sure it would not have unwanted side effects.
The report has been changed to allow implementations to let multiple
versions of a library co-exist.