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

From: John Griffin (jg at ittalentteam.com)
Date: Sat Aug 17 16:52:16 EDT 2013

> (define (hash-equivalent? a b)
>   (for/and ([(k v) (in-hash a)])
>     (and (hash-has-key? b k)
>          (equal? (hash-ref b k) v))))
>

It looks to me that this is true if a has a subset of b's keys.  If that's true, an easy addition to the check is that (hash-count) is the same.

------
John Griffin, CTO
IT Talent Team, LLC
www.ittalentteam.com
855-488-8326






On Aug 17, 2013, at 12:00 PM, users-request at racket-lang.org wrote:

> Send users mailing list submissions to
> 	users at racket-lang.org
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> 	http://lists.racket-lang.org/users/listinfo
> or, via email, send a message with subject or body 'help' to
> 	users-request at racket-lang.org
> 
> You can reach the person managing the list at
> 	users-owner at racket-lang.org
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of users digest..."
> 
> 
> [Racket Users list:
> http://lists.racket-lang.org/users ]
> 
> 
> Today's Topics:
> 
>   1. Re: (check-equal? hash1 hash2) fails (Robby Findler)
>   2. Re: (check-equal? hash1 hash2) fails (J G Cho)
>   3. Re: (check-equal? hash1 hash2) fails (Greg Hendershott)
>   4. Re: (check-equal? hash1 hash2) fails (Greg Hendershott)
> 
> 
> ----------------------------------------------------------------------
> 
> Message: 1
> Date: Sat, 17 Aug 2013 08:18:48 -0500
> From: Robby Findler <robby at eecs.northwestern.edu>
> To: J G Cho <gcho at fundingmatters.com>
> Cc: Racket mailing list <users at racket-lang.org>
> Subject: Re: [racket] (check-equal? hash1 hash2) fails
> Message-ID:
> 	<CAL3TdOPVk9TBVq--doeMg5mPmeXWLGXHp4VK_4vUsdD1S_MJPg at mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
> 
> 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
>> 
>> 
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.racket-lang.org/users/archive/attachments/20130817/371d8837/attachment-0001.html>
> 
> ------------------------------
> 
> Message: 2
> Date: Sat, 17 Aug 2013 09:27:08 -0400
> From: J G Cho <gcho at fundingmatters.com>
> To: Robby Findler <robby at eecs.northwestern.edu>
> Cc: Racket mailing list <users at racket-lang.org>
> Subject: Re: [racket] (check-equal? hash1 hash2) fails
> Message-ID:
> 	<CAPW2k0So6FSBeheV29ukVK2aByRY4ir7g9kE64J-a5app70cQQ at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
> 
> 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
>>> 
>>> 
>> 
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.racket-lang.org/users/archive/attachments/20130817/ecd43d2b/attachment-0001.html>
> 
> ------------------------------
> 
> Message: 3
> Date: Sat, 17 Aug 2013 09:57:36 -0400
> From: Greg Hendershott <greghendershott at gmail.com>
> To: J G Cho <gcho at fundingmatters.com>
> Cc: Racket mailing list <users at racket-lang.org>,	Robby Findler
> 	<robby at eecs.northwestern.edu>
> Subject: Re: [racket] (check-equal? hash1 hash2) fails
> Message-ID:
> 	<CAGspUn345MEBGQurqJbNM5xiUfqySqHrc1KhsB91mK1xoJOpwA at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
> 
> 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
>> 
> 
> 
> ------------------------------
> 
> Message: 4
> Date: Sat, 17 Aug 2013 10:00:37 -0400
> From: Greg Hendershott <greghendershott at gmail.com>
> To: J G Cho <gcho at fundingmatters.com>
> Cc: Racket mailing list <users at racket-lang.org>,	Robby Findler
> 	<robby at eecs.northwestern.edu>
> Subject: Re: [racket] (check-equal? hash1 hash2) fails
> Message-ID:
> 	<CAGspUn21F48UvtjOt0Um4g2ruuA45So87nkBQb8or1c48p8y7w at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
> 
> 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
>>> 
> 
> 
> End of users Digest, Vol 96, Issue 55
> *************************************

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130817/187bc143/attachment-0001.html>

Posted on the users mailing list.