The following two code snippets behave very differently, depending only on the order you define the functions. I find this behavior surprising, and probably not intended.
(ns jimka-test
(:require [clojure.pprint :refer [cl-format]]))
(declare f)
(defn g []
(map f '(1 2 3)))
(def ^:dynamic f (fn [x] (* x x)))
(defn h []
(assert (= (g) '(1 4 9)))
(binding [f (fn [x] (+ x x))]
(assert (= (g) '(2 4 6))
(cl-format false "(g) returned ~A" (g)))))
(h)
Now swap the order of definitions of f
and g
.
(ns jimka-test
(:require [clojure.pprint :refer [cl-format]]))
(declare f)
(def ^:dynamic f (fn [x] (* x x)))
(defn g []
(map f '(1 2 3)))
(defn h []
(assert (= (g) '(1 4 9)))
(binding [f (fn [x] (+ x x))]
(assert (= (g) '(2 4 6))
(cl-format false "(g) returned ~A" (g)))))
(h)
My suggestion is that if a variable is declared non-dynamic, then a later definition as dynamic should issue a warning.
This issue was also discussed on clojureverse