Clojure

Clojure 1.3+ can't intern a dynamic var

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: Release 1.3, Release 1.4
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

In Clojure 1.3+, interned vars don't set the dynamic field in clojure.lang.Var and can't be used in a binding:

user=> (intern ns (with-meta 'dyna-var {:dynamic true}) 100)
user=> (binding [dyna-var "one hundred"] dyna-var)
;=> IllegalStateException Can't dynamically bind non-dynamic var: user/dyna-var clojure.lang.Var.pushThreadBindings (Var.java:339)

The var has the right metadata

user=> (meta #'dyna-var)
;=> {:ns #<Namespace user>, :name dyna-var, :dynamic true}

But doesn't set the dynamic flag on the var:

user=> (.isDynamic #'dyna-var)
;=> false

The push-thread-bindings function looks for the .dynamic flag. Vars created via def have it:

user=> (def ^:dynamic def-dyna-var 100)
user=> (.isDynamic #'def-dyna-var)
;=> true

Along with the metadata

user=> (meta #'def-dyna-var)
{:ns #<Namespace user>, :name def-dyna-var, :dynamic true, :line 6, :file "NO_SOURCE_PATH"}

Activity

Hide
Timothy Baldridge added a comment -

This is actually an enhancement. The Var.java and Namespace.java code does not attempt to read the metadata on the var. Instead, the compiler handles this at compile time. If you would like to see this behavior changed, feel free to bring it up on clojure-dev, and we'll discuss it.

Closing until that time.

Show
Timothy Baldridge added a comment - This is actually an enhancement. The Var.java and Namespace.java code does not attempt to read the metadata on the var. Instead, the compiler handles this at compile time. If you would like to see this behavior changed, feel free to bring it up on clojure-dev, and we'll discuss it. Closing until that time.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: