[r6rs-discuss] [Formal] Version reference syntax is overly complex.

From: Shiro Kawai <shiro>
Date: Wed, 13 Jun 2007 22:18:38 -1000 (HST)

---
This message is a formal comment which was submitted to formal-comment at r6rs.org, following the requirements described at: http://www.r6rs.org/process.html
---
Submitter: Shiro Kawai (shiro at lava.net)
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 <version reference> and <sub-version reference>
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 <sub-version reference> level and/or/not/>=/<=
keywords are only useful when it appears at the last position
in <version reference>.  On the other hand, whenever more than
one sub-version is involved in the operation, we have to fall
back to <version-reference> 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
<sub-version reference> syntax.
I propose two alternative ideas.
Suggested alternative #1
------------------------
Change the <version reference> syntax to the following:
 <version-reference> : ()
                     | (<sub-version> . <version-reference>)
                     | (or  <version-reference> ...)
                     | (and <version-reference> ...)
                     | (not . <version-reference>)
                     | (>=  . <version>)
                     | (<=  . <version>)
Semantics:
  A <version-reference> Vr matches a <version> V when:
   - Vr is ()
   - V  is () and Vr is (0 ...)
   - (car Vr) is <sub-version>, and (eqv? (car Vr) (car V)),
     and (cdr Vr) matches (cdr V).
   - (car Vr) is or, and either one of <version-reference>s in (cdr Vr)
     matches V.
   - (car Vr) is and, and all of <version-reference>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 <sub-version> 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.
--shiro
Received on Thu Jun 14 2007 - 04:18:38 UTC

This archive was generated by hypermail 2.3.0 : Wed Oct 23 2024 - 09:15:01 UTC