[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Proposed modifications to R3RS
The following is a series of proposed modifications to and
deletions from R3RS. They are all based on the following two
a) Syntactic sugar should only be added to the language if its
usefulness far outweighs the complexity it introduces
(e.g., I believe that (define (<name> <vars>) <body) as
syntactic sugar for (define <name> (lambda (vars) <body>))
and named-let both fulfill this criterion.) or it is important
for performance reasons that some construct which can be
built from a few primitives be a primitive itself.
b) Overspecification should be avoided as it artificially
prohibits reasonable implementations.
In at least one case, a suggestion to follow has been mentioned
before; but, I feel it is important enough to justify further
1) The DO construct should be eliminated from the language as it
is easily implemented using named-let's or letrec's. Its
syntax is difficult to follow at best, and it is not powerful
enough for many applications. (e.g. One often has a <test>
which is the disjunction of many different forms and wants to
return a different result depending on which form is true.
DO does not give a simple way of implementing this case short
of repeating the conditionals in the <expressions>.) If
people really want DO because of dusty deck problems or
compatibility with CL (Editorial comment: I think this is a
really bad motivation.) lets settle on a macro standard and
let those who want DO have it as a library function (special
2) The CASE statement should be eliminated for the same reasons
as DO. How many of you have ever used a CASE? Would it
really have been less clear had you used a COND? This should
be a library function if it is going to exist at all.
3) I believe that AND is overspecified as it states that "The
<test> expressions are evaluated from left to right, and the
value of the first expression that evaluates to a false value
is returned. Any remaining expressions are not evaluated.
If all the expressions evaluate to true values, the value of
the last expression is returned." This should be replaced by
something like the following: "The <test> expressions are
evaluated from left to right, with evaluation terminating
with the first expression that evaluates to a false value.
Any remaining expressions are not evaluated. If some
expression evaluates to false then a false value is returned,
otherwise a true value is returned." (A similar change should
be made to OR.
A compiler should feel free to replace
(or (a) (not (a)))
with #t if it can prove that A is side-effect free and
terminates without generating an error. Similarly,
(and (fact n) (fact (-1+ n)))
should be replaceable by #t if FACT is the standard recursive
factorial function and N can be proven to be a nonnegative
integer. (These transformations are not possible given the
Also, an implementor is not free to introduce unique true and
false objects which are always returned by predicates.
If one actually wants the old semantics of AND they can
(let ((test1 <test1>))
which I believe is much more transparent, anyway.
4) LAST-PAIR should be eliminated as it is gratuitous at best.
After all, its tail-recursive implementation appears directly
below it in R3RS. Personally, I can see no performance
reason for keeping it, which would be the only possible
P.S. I erroneously stated in a previous message that MIT CScheme
has a feature like call-with-current-continuation for
environments. It does NOT. I was thinking at the time of its
IN-PACKAGE feature which allows one to evaluated an expression in
an existing environments and in my mind is a (loose) environment
analog to throwing to a continuation. I will have to reread
Johnson and Duggan's paper, "Stores and Partial Continuations as
First-Class Objects in a Language and its Environment," from POPL
1988 before I can appropriately comment on the original question
as to whether we should introduce a call-with-current-environment.