Check-eq? not behaving properly in Typed Racket

Consider:

#lang typed/racket/base

(require typed/rackunit)

(: hash->immutable-hash (All (k v) (-> (HashTable k v) (Immutable-HashTable k v))))
(define (hash->immutable-hash htab)
  (if (immutable? htab)
      htab
     '(more code here)))

(define h '#hasheq((a . 1) (b . 2) (c . 3)))
(eq? (hash->immutable-hash h) h) ; => #t
(check-eq? (hash->immutable-hash h) h) ; Fails.

Basically, if passed an immutable table, it's returned, otherwise it creates a new immutable table with the same contents as the original.

When testing the "return the argument if already immutable" case, I can't figure out why check-eq? fails when the equivalent eq? succeeds.
The same test case passed in an standard untyped Racket implementation; it's just in TR that there's a problem.

Hi, @shawnw.

I can't really comment on the why, but it seems like it is a known issue, at least, that Typed Racket and RackUnit don't play well together in this regard.

Sorry for the nothingburger.

An eight year old thread and the issue is still there, yay. (check-true (eq? ... ...)) seems to work though.

1 Like

The explanation is simple. The types compile to contracts before values escape to untyped code, possibly a library. Some contracts wrap values in a way that obscures pointer equality.

I bumped into this issue myself over the summer when I created a TR benchmark from a little project I wrote. I went back and questioned why I used eq? and not equal? -- @robby 's old question from our 2004 paper. No I didn't need to use eq.