I spend a whole day doing research on lexical and dynamic scoping in Clojure (and Lisp). When I thought I finally understood, I made this example and was super surprised that it didn't return what I expected:
(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)
;; dynamically rebind dynamic-var
(binding [dynamic-var "this is some new content for the dynamic var"]
(function-using-dynamic-var))
(function-using-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))
;; lexically rebind non-dynamic-var
(def non-dynamic-var "this is some new content that won't be used")
(function-using-non-dynamic-var))
I'm declaring a normal and a dynamic var, then a respective function that uses each var and then I try what happens if I rebind/redefine the vars. Output from a call of some-function is:
this is a dynamic var
this is some new content for the dynamic var
this is a non dynamic var
this is a non dynamic var
this is some new content that won't be used
Output is as expected except for the last one. I can't get my head around why this would actually output the new value. As I understood lexical and dynamic scoping, this should return still the old value, because what the function function-using-non-dynamic-var sees for non-dynamic-var should still be the definition from Line 1 in my opinion because it's lexical scoping. But apparently I got it wrong, can anybody explain and make sense out of it?