On Wed, Dec 1, 2010 at 12:45 AM, Sunil S Nandihalli <sunil.nandiha...@gmail.com> wrote: > Hello everybody, > Out of curiosity I tried the following > user> (let [x {:a 10} > > > y (update-in x [:a] identity)] > > > [(identical? x y) > > > (= x y)]) > [true true] > > > user> > and was very pleasantly surprised with the findings... > I was expecting the result to be [false true] .. > I am just wondering how this was made possible.
Looks like assoc does this: user=> (def a {:x 1 :y 2}) #'user/a user=> (def b (assoc a :x 1)) #'user/b user=> (identical? a b) true I thought this could be an artifact of the small map implementation (PersistentArrayMap) that wouldn't work with bigger maps (PersistentHashMap) but: user=> (def a (zipmap (range 15) (map #(* % %) (range 15)))) #'user/a user=> (def b (assoc a 2 4)) #'user/b user=> (identical? a b) true user=> (.getClass a) clojure.lang.PersistentHashMap So, it looks like assoc returns its first argument if the key is already mapped to the same value. A further test shows that it works if the already mapped value and the value passed to assoc are identical, but not if they are equal but non-identical: user=> (def s1 "foo") #'user/s1 user=> (def s2 (apply str (seq s1))) #'user/s2 user=> (= s1 s2) true user=> (identical? s1 s2) false user=> (def a (assoc a 16 s1)) #'user/a user=> (def b (assoc a 2 4)) #'user/b user=> (identical? a b) true user=> (def b (assoc a 16 s1)) #'user/b user=> (identical? a b) true user=> (def b (assoc a 16 s2)) #'user/b user=> (identical? a b) false user=> (= a b) true This means you can't rely on it for numbers. Boxing small integers (in the range of a signed byte) results in an interned value, so in Clojure every 2 is identical to every other 2, and every 127 identical to every other 127, and all -128s are identical, etc. But larger numbers, and non-integers, won't exhibit this: user=> (def b (assoc a 14 196)) #'user/b user=> (= a b) true user=> (identical? a b) false The 196 computed by applying #(* % %) to 14 and the literal 196 in the assoc weren't identical, though they were equal. -- 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 Note that posts from new members are moderated - please be patient with your first post. 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