- lexical scope (static scope): dependent only on the program text.
- dynamic scope: dependent on the runtime call stack.
(def x 1)
default Var isstatic
, usinglet
for local Var,with-redefs
to change the root binding var within its scope (visible in all threads).(def ^:dynamic x 1)
dynamic Var, usingbinding
to change value (thread-local, cannot be seen by any other thread).
In example bellow:
binding
only changes the value of*dynamic-var*
within the scope of the binding expressiondef
changes the root definition ofnon-dynamic-var
from the point of execution on- using
let
to rebindnon-dynamic-var
, the change is only local and won’t affect the top-levelnon-dynamic-var
(def non-dynamic-var "this is a non dynamic var")
(def ^:dynamic *dynamic-var* "this is a dynamic var")
(defn function-using-dynamic-var []
(println *dynamic-var*))
(defn function-using-non-dynamic-var []
(println non-dynamic-var))
(defn some-function []
(function-using-dynamic-var) ;;=> this is a dynamic var
;; dynamically rebind dynamic-var
(binding [*dynamic-var* "this is some new content for the dynamic var"]
(function-using-dynamic-var)) ;;=> this is some new content for the dynamic var
(function-using-non-dynamic-var) ;;=> this is a non dynamic var
;; locally rebind non-dynamic-var
(let [non-dynamic-var "this is some new content that won't be used"]
(function-using-non-dynamic-var)) ;;=> this is a non dynamic var
;; lexically (and globally) rebind non-dynamic-var
(def non-dynamic-var "this is some new content that will be used")
(function-using-non-dynamic-var) ;;=> this is some new content that will be used
)