Внесение наименьшего возможного изменения в ваш код, чтобы заставить его работать:
(def ^:dynamic z nil)
(def ax '(fn x [] (+ 1 z)))
(binding [z 4]
(str ((eval ax)))
)
Два изменения определяют z как динамическую переменную, так что имя разрешается, и ставят еще одну скобку (evalax), потому что ax возвращает функцию.
Немного приятнее изменить определение топора:
(def ^:dynamic z nil)
(def ax '(+ 1 z))
(binding [z 4]
(str (eval ax))
)
Таким образом, оценка ax сразу же дает желаемый результат, а не возвращаетфункция, которая делает это.
Еще раз лучше пропустить eval:
(def ^:dynamic z nil)
(defn ax [] (+ 1 z))
(binding [z 5]
(str (ax))
)
Но лучше всего не иметь z, плавающий как var, и передавать его в axкак предложили Мимсбрунн и Йост.