Can’t dynamically bind non-dynamic var in Clojure 1.3 and on

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.
Be Sociable, Share!
This entry was posted in Languages.

2 Responses to Can’t dynamically bind non-dynamic var in Clojure 1.3 and on

  1. Meikel says:

    It seems I have a different 1.3.0 final version than you do?

    Clojure 1.3.0
    user=&gt; (clojure-version)
    "1.3.0"
    user=&gt; (def ^:dynamic *d* 5)
    #'user/*d*
    user=&gt; (binding [*d* 7] *d*)
    7
    user=&gt; (def *c* 5)
    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/*c*
    user=&gt; (binding [*c* 7] *c*)
    IllegalStateException Can't dynamically bind non-dynamic var: user/*c*  clojure.lang.Var.pushThreadBindings (Var.java:33
    9)
  2. Could it be that lein repl messes it up?! I ran your sexprs with a standalone installation of Clojure 1.3.0 and it worked fine. When I fired up lein2 repl (Leiningen 2.0.0-SNAPSHOT on Java 1.6.0_22 Java HotSpot(TM) 64-Bit Server VM) it yelled at me with the error message. I believe I’ll have to report the issue against Leiningen -> https://github.com/technomancy/leiningen/issues/446.

Leave a Reply

%d bloggers like this: