Making minimal changes to the code to make it work:
(def ^:dynamic z nil) (def ax '(fn x [] (+ 1 z))) (binding [z 4] (str ((eval ax))) )
Two changes define z as a dynamic var, so the name resolves and puts another pair around (eval ax), because ax returns a function.
A little nicer to change the definition of ax:
(def ^:dynamic z nil) (def ax '(+ 1 z)) (binding [z 4] (str (eval ax)) )
So, ax evaluation immediately gets the result you want, rather than returning a function that does this.
Try skipping eval again:
(def ^:dynamic z nil) (defn ax [] (+ 1 z)) (binding [z 5] (str (ax)) )
But it’s best not to have z floating around like var and pass it to the ax, as suggested by Mimsbrunnr and Joost.
source share