[Reproducing what I posted on comp.lang.scheme, repeating some of what's
been said here in the meantime.]

John Cowan <johnwco...@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

_______________________________________________
r6rs-discuss mailing list
r6rs-discuss@lists.r6rs.org
http://lists.r6rs.org/cgi-bin/mailman/listinfo/r6rs-discuss

Reply via email to