Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Clojure by

Using clojure 1.10.3:

user> (def p (promise))
#'user/p
user> (def wrapper
        (reify
          clojure.lang.IDeref
          (deref [_] @p)))
#'user/wrapper
user> wrapper ;; => repl hangs here

In above session the repl blocks on the last statement. I do not see why that is. I would expect @wrapper to block, evaluating wrapper however I expected it to return an Object of some kind. Am I missing something here?

1 Answer

+2 votes
by
selected by
 
Best answer

Your REPL is trying to print wrapper in some useful manner, and that includes the value that you'd get after deref'ing it:

(defn- deref-as-map [^clojure.lang.IDeref o]
  (let [pending (and (instance? clojure.lang.IPending o)
                     (not (.isRealized ^clojure.lang.IPending o)))
        [ex val]
        (when-not pending
          (try [false (deref o)]
               (catch Throwable e
                 [true e])))]
    {:status
     (cond
      (or ex
          (and (instance? clojure.lang.Agent o)
               (agent-error o)))
      :failed

      pending
      :pending

      :else
      :ready)

     :val val}))

(defmethod print-method clojure.lang.IDeref [o ^Writer w]
  (print-tagged-object o (deref-as-map o) w))

Note that printing out promise works just fine because the first function above explicitly checks for it.

...