[racket] (check-equal? hash1 hash2) fails

From: Greg Hendershott (greghendershott at gmail.com)
Date: Sat Aug 17 10:00:37 EDT 2013

p.s. Probably better names would be `hash=?` and `dict=?`. Following
the example of `string=?`, `symbol=?`, etc.

On Sat, Aug 17, 2013 at 9:57 AM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> Well you could write your own predicate -- what you expected
> `hash-equal?` to be. Let's call it `hash-equivalent?`:
>
> #lang racket
>
> (define (hash-equivalent? a b)
>   (for/and ([(k v) (in-hash a)])
>     (and (hash-has-key? b k)
>          (equal? (hash-ref b k) v))))
>
> ;; Testing
> (require rackunit)
> (define assocs '([a 0] [b 1]))
> (define m (make-hash assocs))
> (define i (make-immutable-hash assocs))
> (check-true (hash-equivalent? m m))
> (check-true (hash-equivalent? i i))
> (check-true (hash-equivalent? m i))
> (check-false (hash-equivalent? (make-hash '([a 0])) (make-hash '([a 1]))))
> (check-false (equal? m i))
>
> But actually, these days I would probably instead write a
> `dict-equivalent?`, since it will work with all the hash variants,
> association lists, and so on:
>
> (define (dict-equivalent? a b)
>   (for/and ([(k v) (in-dict a)])
>     (and (dict-has-key? b k)
>          (equal? (dict-ref b k) v))))
>
> ;; Testing
> (check-true (dict-equivalent? m m))
> (check-true (dict-equivalent? i i))
> (check-true (dict-equivalent? m i))
> (check-false (dict-equivalent? (make-hash '([a 0])) (make-hash '([a 1]))))
>
> p.s. There is no `dict-equal?`, so I suppose you could name it that
> instead. Not sure if that would be less confusing, or more so.
>
>
> On Sat, Aug 17, 2013 at 9:27 AM, J G Cho <gcho at fundingmatters.com> wrote:
>> You were right on.
>>
>> So I converted one of the mutable and it worked:
>> (make-immutable-hash  (hash->list mutable-hash))
>>
>> Is there a better way?
>>
>>
>> On Sat, Aug 17, 2013 at 9:18 AM, Robby Findler <robby at eecs.northwestern.edu>
>> wrote:
>>>
>>> Those are equal if they are both mutable or both immutable. Probably one
>>> is mutable and the other isn't (this, unfortunately, doesn't show up in the
>>> print outs). It is quite confusing, I agree.
>>>
>>> > (equal? #hash((6 . 1) (4 . 1) (3 . 2) (2 . 2)) #hash((2 . 2) (3 . 2) (4
>>> > . 1) (6 . 1)))
>>> #t
>>>
>>> Robby
>>>
>>>
>>>
>>> On Sat, Aug 17, 2013 at 8:13 AM, J G Cho <gcho at fundingmatters.com> wrote:
>>>>
>>>> FAILURE
>>>> actual:     #hash((6 . 1) (4 . 1) (3 . 2) (2 . 2))
>>>> expected:   #hash((2 . 2) (3 . 2) (4 . 1) (6 . 1))
>>>> name:       check-equal?
>>>>
>>>> I tried alternative like
>>>> (check-true (hash-equal? hash1 hash2))
>>>>
>>>>  but it turns out hash-equal? is not what I expected it to be.
>>>>
>>>> Other than writing a custom comparison, is there a handy way to compare 2
>>>> #hash?
>>>>
>>>> jGc
>>>>
>>>> ____________________
>>>>   Racket Users list:
>>>>   http://lists.racket-lang.org/users
>>>>
>>>
>>
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>

Posted on the users mailing list.