binding & pmap interaction change?
binding, clojure, dynamic-variables, pmap, thread-local
Solution
starting in 1.3 the set of local bindings are sent to pmap along with the function. So as long as you mark the var ^:dynamic this is no longer a problem. This feature it called Binding Conveyance and is included in the 1.3 changelog:
from: https://github.com/clojure/clojure/blob/1.3.x/changes.txt
Clojure APIs that pass work off to other threads (e.g. send, send-off, pmap, future) now convey the dynamic bindings of the calling thread:
(def ^:dynamic *num* 1)
(binding [*num* 2] (future (println *num*)))
;; prints "2", not "1"
Problem
There are several somewhat old blog posts out there advising caution when mixing dynamic variables, `binding`, and `pmap`, e.g. here, where we get the following code snippet: ``` user=> (def *foo* 5) #'user/*foo* user=> (defn adder [param] (+ *foo* param)) #'user/adder user=> (binding [*foo* 10] (doseq [v (pmap adder (repeat 3 5))] (println v))) 10 10 10 nil ``` But that's not what happens when I run that code (changing the first line to `(def ^:dynamic *foo* 5)`). I get three `15`s as output (using Clojure 1.4), just as you would naïvely expect—that is, with the change in the binding form seen by the function passed to pmap. Have the way thread-local bindings and pmap interact changed? I can't find this documented anywhere.