I'm porting working Clojure code (in a Leiningen project) from 1.2 to 1.3 and having problems. In addition to the code itself no longer working, I'm getting dozens of warning messages like this one:
Warning: *tooltip-width* not declared dynamic and thus is not dynamically rebindable,
but its name suggests otherwise. Please either indicate ^:dynamic *tooltip-width*
or change the name.
This is happening even though I have already made what look like the correct modifications to vars that I'm using to maintain state. For the error above, for example, the code already includes this:
(def ^:dyanamic *tooltip-width* (* 1.8 *slip-width*))
I get these errors in two places: first, from the command line, as a result of executing lein swank
; and second, from the Emacs REPL, after compiling my core.clj
file using C-c C-w
.
To be absolutely complete, here is my project.clj
file:
(defproject infwb "1.0.0-SNAPSHOT"
:description "an evolving, experimental workspace for manipulating infocards"
:main infwb.core
:dependencies [[org.clojure/clojure "1.3"]
[seesaw "1.2.1"]
[org.clojars.gw666/sxqj "beta2"]
[org.clojars.gw666/piccolo2dcore "1.3"]
[org.clojars.gw666/piccolo2dextras "1.3"]
[com.miglayout/miglayout "3.7.4"]
]
:dev-dependencies [[swank-clojure "1.3.2"]
[org.clojars.weavejester/autodoc "0.9.0"]]
:autodoc {:name "Infocard Workbench (InfWb)",
:web-src-dir "https://github.com/gw666/infwb/blob"})
In addition to getting my code working, I'd like to understand why I'm getting these errors and why I'm getting them in both places. Thanks for your help.
It's a simple typo.
(def ^:dyanamic ...
should be:
(def ^:dynamic ...
Happens to us all!
You might want to consider using refs or atoms instead of vars to maintain state.
To quote the Clojure documentation:
Vars provide a mechanism to refer to a mutable storage location that can be dynamically rebound (to a new storage location) on a per-thread basis.
(Emphasis mine.)
Vars can be set to a new value (for the current thread) with the binding
macro. Up to Clojure 1.2 any var could be rebound like this, but since Clojure 1.3 vars need to be explicitly declared as ^:dynamic
to allow this. (As far as I know, the reason is a drastic speed-up of var look-ups for the common case of no rebinding.)
It is a common convention (but nothing more) to give vars that are intended to be rebound names like this: *foobar*
. Because of this convention, the compiler gives you a warning when it sees a var named like this that is not declared dynamic.
To sum up:
atom
, ref
(if you need transactions) or agent
(for asynchronous change).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