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

Reply via email to