Ran into a snag about how maps interact with dynamic bindings I thought this channel would find interesting. Consider this snippet:
(def ^:dynamic *boundvar* nil)
(defn myfn [x] [*boundvar* x])
(binding [*boundvar* :a] (map myfn [0 1])) ; STATEMENT 1
(map #(binding [*boundvar* :a] (myfn %)) [0 1]) ; STATEMENT 2
Now I thought that the output of statements 1 and 2 would be the same, but actually:
(binding [*boundvar* :a] (map myfn [0 1])) ; STATEMENT 1
=> ([nil 0] [nil 1])
(map #(binding [*boundvar* :a] (myfn %)) [0 1]) ; STATEMENT 2
=> ([:a 0] [:a 1])
snag Maps are lazily evaluated (and a binding isn't a let)! *boundvar* isn't resolved to a value until the whole map is realized. Fix it like this
(binding [*boundvar* :a] (doall (map myfn [0 1])))
=> ([:a 0] [:a 1])yeah this is a classic laziness issue
may i suggest mapv? it's faster and more efficient than map + doall