[racket] Object% equal? for Hash#

From: Danny Yoo (dyoo at hashcollision.org)
Date: Wed Oct 31 17:07:14 EDT 2012

> But, now I have to had an attribute wich do not have to tested and I can't
> figure the best way out.
>
> Would I investigate with inspector or the equal<%> interface.
> Both ways, I don't know how to do this. The doc is pretty brief about that.

Are you saying that there are fields in your object that you don't
want to be part of the equality test?


If so, it does sound like implementing the equal<%> interface may give
you enough power to express that idea.
(http://docs.racket-lang.org/reference/objectequality.html)


Here's a small example:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket

(define ci-word%
  (class* object% (equal<%>)

    ;; Initialization
    (init-field word)
    (super-new)

    ;; We define equality to ignore case:
    (define/public (equal-to? other recur)
      (string-ci=? word (get-field word other)))


    ;; The hash codes need to be insensitive to casing as well.
    ;; We'll just downcase the word and get its hash code.
    (define/public (equal-hash-code-of hash-code)
      (hash-code (string-downcase word)))

    (define/public (equal-secondary-hash-code-of hash-code)
      (hash-code (string-downcase word)))))

(define h (make-hash))
(hash-set! h (new ci-word% [word "foobar"]) 'value)

;; Of course, we expect this lookup to succeed:
(hash-ref h (new ci-word% [word "foobar"]))

;; but it will also match case-insensitively:
(hash-ref h (new ci-word% [word "FoOBaR"]))

Posted on the users mailing list.