Thanks Ken that was a very detailed teardown and so fast .. Now it makes sense. Sunil.
On Wed, Dec 1, 2010 at 11:29 AM, Ken Wesson <[email protected]> wrote: > On Wed, Dec 1, 2010 at 12:45 AM, Sunil S Nandihalli > <[email protected]> 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 [email protected] > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > [email protected]<clojure%[email protected]> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en
