I've been trying for a while to solve this nREPL ticket and I'm out of ideas, so I decided to ask for a bit of help here.
Basically we need to be bind *print-namespace-maps* only if it's present or find some way to define if it's not present that doesn't mess up Clojure 1.9+.
Here are some of the things that don't work:
;; compilation error
(when (resolve '*print-namespace-maps*)
(set! *print-namespace-maps* (@bindings #'*print-namespace-maps*)))
;; shadows `clojure.core/*print-namespace-maps*` on 1.9, as the def gets executed always
(when-not (resolve 'clojure.core/*print-namespace-maps*)
(def ^:dynamic *print-namespace-maps*
"Define the var for clojure versions below 1.9"
nil))
Seems that dynamic vars can't be conditionally bound at all, which really sucks, but I guess there must be some way to do something like what we're aiming for.
Take a look at the linked issue for more details. Any help would be much appreciated!
I don't totally understand the details of the linked issue or nREPL impl., but the def behavior is a bit surprising here:
Clojure 1.8.0
user=> (when false (def ^:dynamic *foo* 1))
nil
I would've expected there to be no *foo* var after that evaluation, but it creates an unbound var:
user=> (var-get #'*foo*)
#object[clojure.lang.Var$Unbound 0x20da8800 "Unbound: #'user/*foo*"]
And I suppose that def compiler behavior is what causes the exception in 1.9 in your example:
WARNING: *print-namespace-maps* already refers to: #'clojure.core/*print-namespace-maps* in namespace: user, being replaced by: #'user/*print-namespace-maps*
Maybe a macro could be used so that the resolve check happens during macro expansion, and doesn't emit a def if it resolves:
(defmacro def-dynamic-when-not-resolve [sym value]
(when-not (resolve sym)
`(def ~(vary-meta sym assoc :dynamic true) ~value)))
It seems to work on Clojure 1.8:
Clojure 1.8.0
user=> (def-dynamic-when-not-resolve *print-namespace-maps* 'sure)
#'user/*print-namespace-maps*
user=> *print-namespace-maps*
sure
And on Clojure 1.9:
Clojure 1.9.0
user=> (def-dynamic-when-not-resolve *print-namespace-maps* 'sure)
nil
user=> *print-namespace-maps*
true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With