liveBook · Manning

Identical?

As explained in Clojure: The Essential Reference

identical? is a Clojure function that tests whether two objects occupy the same identity or memory address under Java object semantics.

Use `identical?` when it matters whether two references point to the same object, not merely to equal values. It returns `true` for the same instance and `false` otherwise. Exactly two arguments are required; either may be `nil`, but any other arity throws `clojure.lang.ArityException`. For ordinary value comparisons, use `=` instead. section 6.5 section 6.0

A shared reference

`(let [x #{1 2 3} y x] (identical? x y))` returns `true`: both bindings refer to one set. Equal-looking values need not share that identity. section 6.5

Identity can be surprising for basic values because some are cached or interned. For example, `(identical? (Long. 100) 100)` returns `false`, while `(identical? (Long/valueOf "100") (Long/valueOf "100"))` returns `true`. Do not use identity as a general-purpose equality test. section 6.5

(import 'java.util.concurrent.LinkedBlockingQueue)

(def channel (LinkedBlockingQueue. 1)) ; #1
(def SENTINEL (Object.))               ; #2

(defn encode []                  ; #3
  (let [e (.take channel)]
    (if (identical? SENTINEL e)
      (println "done")
      (do (println (hash e))
          (recur)))))

(defn start []                   ; #4
  (let [out *out*]
    (.start (Thread.
        #(binding [*out* out]
          (encode))))))

(do
  (start)
  (.offer channel :a)
  (.offer channel (Object.))     ; #5
  (.offer channel SENTINEL)
  (.offer channel :a))           ; #6

;; -2123407586
;; 1430420663
;; done

A producer and consumer share a unique sentinel object. The consumer uses `identical?` to stop on that object while processing other queued values normally. section 6.5

How Clojure: The Essential Reference covers it

How deep it goes
Defines the two-argument contract, arity exception, and interning surprises, but does not detail JVM memory mechanisms.
Examples
Uses shared set bindings, cached numeric objects, and a queue consumer that stops on a sentinel.
What it assumes
Assumes familiarity with Clojure bindings while defining reference identity and introducing sentinel values.
What you can do after
Practice/perform identity checks with `identical?` to recognize a sentinel without substituting identity for value equality.
How it connects
Relates reference identity to value equality, Java object semantics, interning, and sentinel values.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.