John Cowan <
johnw...@gmail.com> writes:
> One of the changes between R5RS and R6RS is that (eqv? x x), where
> x is a variable whose value is a procedure, is allowed to return #f.
> The R6RS Rationale, section 11.5.1, says in its entirety:
>
> The definition of eqv? allows implementations latitude in their
> treatment of procedures: implementations are free either to detect or
> to fail to detect that two procedures are equivalent to each other,
> and can decide whether or not to merge representations of equivalent
> procedures by using the same pointer or bit pattern to represent
> both. Moreover, they can use implementation techniques such as
> inlining and beta reduction that duplicate otherwise equivalent
> procedures.
>
> The first sentence of the rationale is only partly true: the R6RS
> gen-counter example shows that if procedures are not operationally
> equivalent, eqv? must treat them as distinct, as was true in R5RS.
> The second sentence does not seem to me to constitute a sufficient
> explanation for results like this:
>
> (let ((x (lambda (x) (+ x 1)))) (eqv? x x)) => #f rather than #t
For most implementations, the only reasonable test of procedure
equivalence is just checking if the two references point to the same
object - essentially using eq?. Also, (simplifying greatly), most
implementations usually allocate a fresh object when evaluating a
`lambda' expression. This means that two different evaluations of
`lambda' expressions usually give non-equivalent procedures in the sense
of `eqv?'.
Now, in the example above, beta-reducing the `let' gives you:
(eqv? (lambda (x) (+ x 1)) (lambda (x) (+ x 1)))
This is the kind of program transformation we wanted to allow in R6RS.
Since one expression has become two, you also generally get two
evaluations of `lambda' expressions, and, hence, two objects that are
not `eqv?'.
> (memv cdr (list car cdr cons)) => #f rather than a list of two elements
This example, I believe, specifically used simple primitives, which can
be compiled to very short open instruction sequences when applied
directly. Converting them into first-class procedures may mean
something similar to eta-expanding them. Again, you get separate `lambda'
expressions, and therefore non-equivalence.
Does this help?
Historical aside: Prior to R6RS, the ML people had ridiculed us for
years for the old behavior of `eqv?'.
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla