Sunil, is there any particular reason why you are looking for when
results of operations have identical? return true, rather than merely
= return true?
If it is for some reduction in allocating new memory when it is not
necessary, then I can understand your motivation, although it really
depends upon the application how often this case would arise in
practice, and thus how much memory it would actually save.
If it is to know where the boundaries are between guaranteed behavior
and non-guaranteed behavior, then I'm all for that kind of education.
In general, you will likely be safer and happier using = whenever you
want to know whether two immutable objects have the same value. Sure,
those values that are = just might happen to be identical, too, but
why rely on such behavior?
identical? has fairly limited practical use, e.g. perhaps in Java
interop, with mutable objects where you wish to know whether two
mutable objects are actually the same one.
Andy
On Nov 30, 2010, at 10:04 PM, Sunil S Nandihalli wrote:
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]
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
--
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