This is not true, you are checking to see if object x implements the IDeref interface, which simply means that you can dereference the object with the @ symbol. What you want is:
(instance? clojure.lang.Ref x)
EDIT:
(Correction of comments).
You can do what you suggested, but this has a drawback in classifying objects made by other users who extend IDeref to be considered a reference type. Also note that vars also behave like reference types, but do not use the IDeref interface.
There are two good options here. You can either write a function that uses the or operator:
(def ref? [x] (or (instance? clojure.lang.Ref x) (instance? clojure.lang.Agent x) ...))
Or you can use protocols to define a new predicate. The advantage of this is its expandability.
(defprotocol Ireference? (reference? [this])) (extend-type java.lang.Object Ireference? (reference? [this] false)) (extend-type nil Ireference (reference? [this] false)) (extend-type clojure.lang.Ref Ireference? (reference? [this] true)) (extend-type clojure.lang.Agent Ireference? (reference? [this] true)) ;;user=> (reference? nil) ;;false ;;user=> (reference? (ref 0)) ;;true
In another example, see http://dosync.posterous.com/51626638
source share