(if-clojure-version-gte version if-branch)(if-clojure-version-gte version if-branch else-branch)(if-java-version-gte version if-branch)(if-java-version-gte version if-branch else-branch)(rebind-dynamic-impl var f args)Clojure creates a lot of layers of dynamic bindings for data-readers (e.g. clojure.main, require, Compiler/load etc). Some of them are not directly nested, but instead siblings. This causes issues even in simplest cases: e.g. loading namespace vs executing a function from that namespace, latter won't see changes made by former.
This might lead to very confusing behaviors, like:
(print/install!)
(defn -main [& args]
(println *data-readers*))
;; => {}
Modifying root binding is not enough, as the changes don't automatically propagate down the stack. Here we are abusing pop/pushBindings to add desired readers to every frame in dynamic vars stack.
Clojure creates a lot of layers of dynamic bindings for *data-readers*
(e.g. clojure.main, require, Compiler/load etc). Some of them are not
directly nested, but instead siblings. This causes issues even in simplest
cases: e.g. loading namespace vs executing a function from that namespace,
latter won't see changes made by former.
This might lead to very confusing behaviors, like:
(print/install!)
(defn -main [& args]
(println *data-readers*))
;; => {}
Modifying root binding is not enough, as the changes don't automatically
propagate down the stack. Here we are abusing pop/pushBindings to add
desired readers to every frame in dynamic vars stack.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |