On Sat, Jan 3, 2009 at 5:35 AM, Martin Wood-Mitrovski
<marvot...@gmail.com> wrote:
>
> On Sat, 3 Jan 2009 01:32:08 -0800 (PST) Jason <jawo...@berkeley.edu> wrote:
>
>>
>> Is this desired behavior for contains?
>>
>> 1:1 user=> (= [1 2] '(1 2))
>> true
>> 1:2 user=> (contains? (hash-set [1 2]) '(1 2))
>> false
>> 1:3 user=> (contains? (sorted-set [1 2]) '(1 2))
>> java.lang.ClassCastException: clojure.lang.PersistentList (repl-1:2)
>> 1:4 user=> (contains? (hash-map [1 2] nil) '(1 2))
>> false
>> 1:5 user=> (contains? (array-map [1 2] nil) '(1 2))
>> true
>>
>> As far as I can figure all five of these should return true (the
>> exception is particularly weird).  Am I missing something here?
>
> Im just starting with clojure but to me it looks right.
>
> In the first case the compare is true because its comparing them by
> value, whereas in all the other cases it fails because you are asking
> if a structure with a vector in it contains a list, which isnt true
> because its not comparing them by value but by identity.

Neither == nor hashes require true identity.

(def v1 [1 2])
(def v2 [1 2])
(def l1 '(1 2))
(def l2 '(1 2))

You can do what I believe are simple pointer comparisons (Java ==)
with 'identical?':
(identical? v1 v1)  ==> true
(identical? l1 l1)  ==> true
(identical? v1 v2)  ==> false
(identical? l1 l2)  ==> false

If hashes used identity, then you wouldn't be able to use v1 to look
up a hash with a key of v2, but you can:

(get (hash-map v1 :found) v2)  ==> :found
(get (hash-map l1 :found) l2)  ==> :found

But as noted originally, hashes are a bit more strict than Clojure =:

(= v1 l1)  ==> true
(get (hash-map v1 :found) l1)  ==> nil

You can see why by calling the 'hash' function directly:

(hash v1)  ==> 994
(hash l1)  ==> -1919631597

The same applies for hash-sets.   ...but not for array-maps or
sorted-maps.  Others have already explained the sorted-map exception,
but it may be worth noting again as the original post demonstrated
that array-maps appear to use =, ignoring the results of 'hash'

(get (array-map v1 :found) l1)  ==> :found

So you can list things that relate to equality in order from most- to
least-strict as: identical?, hash, =

The == function doesn't fit on the scale because for numbers
it seems to act like =, but for non-numbers it just returns false:

(== v1 v1)  ==> false
(identical? 1 1.0)  ==> false
(identical? 1 1M)  ==> false
(== 1 1M 1.0)  ==> true
(= 1 1M 1.0)  ==> true

The value of == is that it's much faster than =, and responds well to
working with primitive numbers:

(time (dotimes [_ 123456789] (=  1 1.0)))  ==> 1350.525414 msecs
(time (dotimes [_ 123456789] (== 1 1.0)))  ==> 18.603425 msecs
(time (dotimes [_ 123456789] (== (int 1) (float 1.0))))  ==> 10.348273 msecs

--Chouser

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to