[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