The following code complies without errors or warnings, but it doesn’t behave as I expected. The problem is that the function f
is forward declared and then the function g
is compiled acknowledging that declaration. Later f
is defined as a dynamic variable and no error/warning is issued.
When function h
rebinds f
using binding
the call to f
within the function g
is not effected by this rebinding.
The fix is to change the declaration to (declare :dynamic f)
.
Of course in this very small test case, it might be obvious what’s wrong. But my original problem was in a large file where the declaration, definition, and use sites were very far away from each other.
Shouldn’t the compiler warn me if I define a dynamic variable which was declared to be non-dynamic?
(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)