In clojure, what is the exact behaviour of identical?

329 Views Asked by At

I am very surprised by the behaviour of identical? in clojure.

(def a (map identity [:a :b])) (identical? (rest a) (rest a)); false

Any idea why identical? returns false?

2

There are 2 best solutions below

5
On BEST ANSWER

identical?:

Tests if 2 arguments are the same object

Since rest creates a new seq object on each invocation, its results are not identical?. The following, however, is:

(def r (rest (map identity [:a :b])))
(identical? r r) ;; => true

Update: As @mfikes pointed out, rest does not always create a new seq. It calls ISeq.more() internally which is implemented per seq type and might yield different results for lists, vectors, lazy seqs, etc.:

(->> [(map identity [:a :b])
      (vector :a :b)
      (list :a :b)]
     (map #(identical? (rest %) (rest %))))
;; => [false false true]
0
On

identical? is the object equality predicate. It returns true if its arguments are the same object/primitive.

Use = over identical?.

identical? is the correct tool when semantics depend on pointer equality, such as testing for an end-of-file sentinel value.

Never use identical? to compare Clojure data structures. Even keywords don't guarantee identical? behaves correctly.