The function that creates the lexical closure can still have referential transparency. For example:
(defn make-adder [x y]
(fn [z] (+ x y z)))
((make-adder 1 2) 3)
-----VS-------------
(def ^{:dynamic} x 1)
(def ^{:dynamic} y 2)
(defn make-adder []
(fn [z] (+ x y z)))
((make-adder) 3)
In the first example, the closure returned is still a function of the arguments passed to make-adder, and it is easy to reason about. In the second example, the closure returned relies on the dynamic value of x and y at run time. I agree that if you close over a reference to a mutable value you can also break referential transparency, but that's the exception and not the rule with clojure since it is immutable by default. With dynamic vars you are almost guaranteed to break referential transparency.
(defn make-adder [x y] (fn [z] (+ x y z)))
((make-adder 1 2) 3)
-----VS-------------
(def ^{:dynamic} x 1) (def ^{:dynamic} y 2)
(defn make-adder [] (fn [z] (+ x y z)))
((make-adder) 3)
In the first example, the closure returned is still a function of the arguments passed to make-adder, and it is easy to reason about. In the second example, the closure returned relies on the dynamic value of x and y at run time. I agree that if you close over a reference to a mutable value you can also break referential transparency, but that's the exception and not the rule with clojure since it is immutable by default. With dynamic vars you are almost guaranteed to break referential transparency.