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 -~----------~----~----~----~------~----~------~--~---