5.92

22 Intensional equality

Mutation exposes yet another sense in which two things may be consider "the same": two things are the same if mutating one mutates the other.

How can we tell if two posns are two different names for the same thing, or if they’re two different posns with the same contents?

For example:

(define p1 (posn% 3 4))
(define p2 (posn% 3 4))

or

(define p1 (posn% 3 4))
(define p2 p1)

These are very different in the presence of mutation. We have a way of testing this: eq?. Similarly, the equal? function checks structural equality.

But that didn’t shed any light on the question. Is there a way we can check this in our language?

Answer: yes. Do some operation to one of them that changes the state of the object, and see if it also happens to the other one.

Drawback: you can’t necessarily undo this operation.

(define (really-the-same? p1 p2)
  ....)

Now we need some operation to perform on p1.

posn%

;; -> (posn% 'black-eye Number)
(define (punch!)
  (begin
    (set-field! x 'black-eye)
    this))
(define sam (posn% 3 4))
(send sam punch!)

"I punched him so hard, I punched him right out of the data defintion."

Now we can define really-the-same?.

(define (really-the-same? p1 p2)
  (begin
    (send p1 punch!)
    (symbol? (send p2 x))))
(really-the-same? p1 p2)
p1

Now p1 is permanently broken, and can’t be undone. So really-the-same? is a very problematic, and you should use eq?, which uses DrRacket’s internal knowledge of where things came from to answer this question without changing the objects.

Question:

(eq? p1 (send p1 punch!))

Produces true.

(send p2 =? (send p2 punch!))

Produces true (or crashes).

(send (send p3 punch!) =? p3)

Produces true (or crashes).

Question: Does intensional equality imply structural equality? Yes.