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

Reply via email to