Re: Comparing DS_HASH_TABLE objects

Eric Bezault <ericb-D6Qt/9opevxWk0Htik3J/[email protected]> Mon, 01 Jun 2009 09:42:23 +0200
Newsgroups gmane.comp.lang.eiffel.gobo.general
Message-ID <[email protected]>
Paul Cohen wrote:
> On Sun, May 31, 2009 at 11:47 PM, Eric Bezault <ericb-D6Qt/9opevxWk0Htik3J/[email protected]> wrote:
>> Paul Cohen wrote:
>>> On Sun, May 31, 2009 at 8:43 PM, Eric Bezault <ericb-D6Qt/9opevxWk0Htik3J/[email protected]> wrote:
>>>>> How do I compare two DS_HASH_TABLE objects for object equality?
>>>> I don't know what you mean. Do you want to consider two
>>>> hash tables equal if the items they contain are equal?
>>> I am aware that there are different ways of defining equality between
>>> two tables t1 and t2. My assumption was something like:
>>>
>>> t1.keys.is_equal (t2.keys) and then
>>> for each key k1 in t1:
>>> (t1 @ k1).is_equal (t2 @ k2)
>>>
>>> I don't think the 'equality_tester':s should be used since they have
>>> more with how DS_HASH_TABLE:s work, than what they contain (though how
>>> they work will of course affect what they contain!).
>> I don't see how `equality_tester' has more to do with how hash
>> table works than what you try to do.
> 
> The 'key_equality_tester' and 'equality_tester' are properties of the
> hash table, not of the keys or the items in the hash_table.

I don't agree with that. Objects can be compared in many different
ways, regardless whether they are used in hash tables or not.
`is_equal' is just one way to compare them, but that does not
mean that the other ways to compare them are not properties of
these objects.



> 
>> I guess you're confusing
>> `equality_tester' with `key_equality_tester'.
> 
> No, I am refering to both.
> 
>> Which brings to
>> my attention the fact that in order to be correct, hash table
>> equality should use `key_equality_tester' to compare keys in
>> your code above, not `is_equal'. Indeed keys might be equal
>> in terms of `is_equal', but they might nevertheless represent
>> two different keys in the hash table (which uses `key_equality_
>> tester' for that).
> 
> Aha, I think I understand what I am asking now! ;-)
> 
> I am asking/looking for a feature in DS_HASH_TABLE that should be
> named something like:
> 
>     are_equivalent, has_the_same_keys_and_items (t: like Current): BOOLEAN
>             -- Does `Current' have the same keys and items as `t'
>             -- when keys and items are compared for equality
>             -- using `is_equal' and for all keys:
>             -- (Current @ key).is_equal (t @ key)?

As I said in my first message, this kind of routine does not
exist in hash table.

> 
> I am interested in comparing the *contents* of the hash tables. Let me
> illustrate with the test case problem I'm trying to solve; in JSON you
> can have an JSON object (associative array) like:
> 
> {"name":"Gustave","surname":"Eiffel"}
> 
> where "name" and "surname" are keys and "Gustave" and "Eiffel" are
> values or items (JSON strings in this case).
> 
> The JSON object above may be represented by two DS_HASH_TABLE
> [UC_STRING, UC_STRING] objects that may/or may not contain the same
> UC_STRING objects as keys and items and that may/or may not have the
> same `key_equality_tester' and/or `equality_tester'. If they don't
> have the same `key_equality_tester' they should not be considered
> equal as *hash tables*. I fully agree with that.
> 
> However, I'm looking for the feature where they *will be considered
> equal/equivalent/the same* if one only looked at the key and item
> values and how keys are mapped to items.
> 
>>>> If so, I don't
>>>> think there is a feature for that in DS_HASH_TABLE.
>>>> The implementation of `is_equal' uses '=' to compare
>>>> items.
>>> Yes. I saw that. Why '=' and not 'is_equal'?
>> But why `is_equal' and not any other kind of comparison?
> 
> Simply because 'is_equal' matches my understanding of the semantics of
> obj1.is_equal (obj2) as meaning "is the object obj1 considered to be
> equal to obj2".

In Gobo, by design, I try to avoid using `is_equal' as much as
possible. First, it is cat-call error-prone. Second, as already said
above, there are many ways to compare objects, and `is_equal'
is not necessarily the best one. That's why I introduced the
notion of equality tester in Gobo.


> 
> The current solution would mean that two hash tables, that have the
> same `key_equality_tester' and `equality_tester', the same keys but
> where the items do not reference the same objects yet the items are
> equal in an 'is_equal' sense, are not equal!? That feels strange to
> me. (I know my feelings can't be used as a basis for formal
> specifications). Eg:
> 
>     local
>         t1, t2: DS_HASH_TABLE [STRING, STRING]
>         key: STRING
>         value: STRING
>         b: BOOLEAN
>     do
>         create t1.make (2)
>         key := "name"
>         value := "Gustave"
>         t1.put (value, key)
>         key := "surname"
>         value := "Eiffel"
>         t1.put (value, key)
>         create t2.make (2)
>         key := "name"
>         value := "Gustave"
>         t2.put (value, key)
>         key := "surname"
>         value := "Eiffel"
>         t2.put (value, key)
>         b := t1.is_equal (t2) -- b is False. This feels strange!
>     end

It does not feel strange for someone who wants to know whether
the hash table contains the same item objects and not duplicates.
By default, when not redefined, objects are considered `is_equal'
if their attributes (i.e. their content) are the same objects.
That's what is done here for hash tables: do they have the same
content (i.e. the same item objects)? So it does not feel stranger
than this:

   c1, c2: CELL [STRING]
   value: STRING
   b: BOOLEAN
   ...
   create c1
   value := "Eiffel"
   c1.put (value)
   create c2
   value := "Eiffel"
   c2.put (value)
   b := c1.is_equal (c2) -- b is False

> 
>> It uses '=' to compare items because `is_equal' is used
>> in the postcondition of `copy/twin', and their implementation
>> in hash table does not clone the items.
> 
> I don't understand the problem. Using `is_equal' to compare items
> would not break the postcondition in `copy'

It would not break the postcondition, but it would not be
as precise as it could. We can say more than just that the
items are equal. They are the same.

> 
> So, to summarize:
> 
>    1. I don't understand conceptually why t1.is_equal (t2) = False in
> the example given above. And I see that HASH_TABLE works the same.

Let's consider strings. We can consider that two strings are equal
if they are case-sensitive equal (this is typically what `is_equal'
implements) or if they are case-insensitive equal. When writing
an Eiffel compiler, the strings representing Eiffel identifiers
should be considered equal if they are case-insensitive equal.
So, "foo" and "Foo" will be considered equal using this criterion
even though `is_equal' will return false.

>    2. I'd like an `is_equivalent'  or `has_the_same_keys_and_items'
> feature in DS_HASH_TABLE that ignores `key_equality_tester' and
> `equality_tester'!

The fact that the classes in Gobo try to avoid using `is_equal'
is a design decision. I stopped using `is_equal' to compare objects.
In my opinion this is a caveat of Eiffel to do so. I only use
it to express what copy/twin do.

-- 
Eric Bezault
mailto:ericb-D6Qt/9opevxWk0Htik3J/[email protected]
http://www.gobosoft.com


------------------------------------

To Post a message, send it to:   [email protected]
To Unsubscribe, send a blank message to: [email protected]! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/gobo-eiffel/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/gobo-eiffel/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:[email protected] 
    mailto:[email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/