The docs on when a value is a chaperone of another are confusing and
don't seem to match the implementation.
They seem to say that (and (not (chaperone? a)) (not (chaperone? b))
(equal? a b)) implies (chaperone-of? a b) but this does not seem to
hold.
They also change behavior if I switch from a transparent structure to
a structure where I explicitly implement equality.
#lang racket
(struct foo (v)
#:property prop:equal+hash
(list
(lambda (l r equal?)
(equal? l r))
(lambda (v hash)
(hash v))
(lambda (v hash)
(hash v))))
#;
(struct foo (v) #:transparent)
(define foo1 (foo (box 0)))
(define foo2 (foo (box 0)))
(define foo3 (foo (foo-v foo1)))
"1 2"
(equal? foo1 foo2)
(chaperone-of? foo1 foo2)
(chaperone-of? foo2 foo1)
"1 3"
(equal? foo1 foo3)
(chaperone-of? foo1 foo3)
(chaperone-of? foo3 foo1)
;;-----------
"1 2"
#t
#f
#f
"1 3"
#t
#f
#f
I expect these to all return true but only the equals do. If I switch
to transparent equality then 1 and 3 are equal.
The goal in this is to have my own struct type (free identifier
tables) be able to support chaperone-of? like immutable hashes do:
(chaperone-of? (hash 'a 'b) (hash 'a 'b)) ;; => #t
These are different hashes but are chaperones of each other. The
importance of this is chaperone contracts on free identifier tables
need to make a copy like hash/c does on immutable hashes.