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

0 votes
in Errors by
closed by

Problem Statement

The function clojure.core/deref throws a hard-to-decipher ClassCastException when given an object that's not an instance of clojure.lang.IDeref or java.util.concurrent.Future. In my experience on-boarding new Clojure users (at my job and in my open source projects), this comes up and can be quite confusing as it doesn't point to anything obvious in the code. Even with the stack trace, it just points to deref-future's definition (instead of a specific line within the function body), which further confuses.

Discussion

On Slack, I proposed changing the implementation of deref to be something like (cond (instance? clojure.lang.IDeref ref) ... (instance? java.util.concurrent.Future ref) ... :else (throw (IllegalArgumentException (str ref " cannot be deref'd as it is of type " (class ref) ".")).

Sean Corfield brought up that such a fix would cost performance for all non-IDeref uses of deref, which I acknowledged but find acceptable.

Repro:

user=> (def a {})
#'user/a

user=> @a
Execution error (ClassCastException) at user/eval22861 (REPL:0).
class clojure.lang.PersistentArrayMap cannot be cast to class java.util.concurrent.Future (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.util.concurrent.Future is in module java.base of loader 'bootstrap')

user=> (pst)
ClassCastException class clojure.lang.PersistentArrayMap cannot be cast to class java.util.concurrent.Future (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
    clojure.core/deref-future (core.clj:2315)
    clojure.core/deref-future (core.clj:2315)
    clojure.core/deref (core.clj:2338)
    clojure.core/deref (core.clj:2323)
    user/eval22863 (NO_SOURCE_FILE:0)
    user/eval22863 (NO_SOURCE_FILE:-1)
    clojure.lang.Compiler.eval (Compiler.java:7194)
    clojure.lang.Compiler.eval (Compiler.java:7149)
    clojure.core/eval (core.clj:3215)
    clojure.core/eval (core.clj:3211)
    clojure.main/repl/read-eval-print--9206/fn--9209 (main.clj:437)
    clojure.main/repl/read-eval-print--9206 (main.clj:437)
by
Looks like this is a duplicate of https://ask.clojure.org/index.php/1553/error-message-when-calling-deref-on-non-ideref-is-unhelpful which I unfortunately didn't find until after posting.
by
Thanks, I also did not find that despite searches on both ask and jira, will dupe this to that.
...