I’ve already described the issue of Can’t dynamically bind non-dynamic var in Can’t dynamically bind non-dynamic var in Clojure 1.3. While learning about defs, symbols and vars, I again ran into this issue. I can see now that I made a mistake using Clojure 1.3 not 1.3.0-alpha6 in the title of the past blog entry as it seems broken in the final version 1.3.0.
user=> (clojure-version) "1.3.0" user=> (def b 3) #'user/b user=> (binding [b 4]) IllegalStateException Can't dynamically bind non-dynamic var: user/b clojure.lang.Var.pushThreadBindings (Var.java:339) user=> (def *c* 5) #'user/*c*Warning: *c* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *c* or change the name. user=> (def ^:dynamic *d* 5) #'user/*d*Warning: *d* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *d* or change the name.
It turns out that it was however fixed in the recent version of Clojure 1.4.0-beta3 and on.
You can download Clojure 1.4.0-beta3 and check it out yourself (I strongly recommend using leiningen to do the test).
$ wget -O clojure-1.4.0-beta3.jar http://search.maven.org/remotecontent?filepath=org/clojure/clojure/1.4.0-beta3/clojure-1.4.0-beta3.jar $ java -jar clojure-1.4.0-beta3.jar Clojure 1.4.0-beta3 user=> (def ^:dynamic *d* 5) #'user/*d* user=> (binding [*d* 10] *d*) 10
I also tested it out with the recent build off the sources of Clojure.
$ ant
Buildfile: /Users/jacek/oss/clojure/build.xml
...
jar:
[jar] Building jar: /Users/jacek/oss/clojure/clojure-1.4.0-master-SNAPSHOT.jar
[copy] Copying 1 file to /Users/jacek/oss/clojure
all:
BUILD SUCCESSFUL
Total time: 1 minute 34 seconds
$ java -jar clojure-1.4.0-master-SNAPSHOT.jar
Clojure 1.4.0-master-SNAPSHOT
user=> (def ^:dynamic *d* 5)
#'user/*d*
user=> (meta (var *d*))
{:ns #<Namespace user>, :name *d*, :dynamic true, :line 1, :file "NO_SOURCE_PATH"}
user=> (binding [*d* 10] *d*)
10
I’ll have to stick with the version clojure-1.4.0-beta3 for the time being.
However, it looks like I’ll also have to use (def ^{:dynamic true} *server*) as lein2 compile finished with the following error:
Caused by: java.lang.IllegalArgumentException: Unable to resolve classname: :dynamic at clojure.lang.Compiler$HostExpr.tagToClass(Compiler.java:916) at clojure.lang.Compiler$VarExpr.getJavaClass(Compiler.java:512) at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:807) at clojure.lang.Compiler.analyzeSeq(Compiler.java:5369) ... 47 more Compilation failed.
