绑定和pmap交互改变?

ben*_*n w 5 binding clojure thread-local pmap dynamic-variables

有几个老有所博客帖子混合动态变量时,在那里建议谨慎binding,并且pmap,如在这里,我们得到了下面的代码片段:

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
Run Code Online (Sandbox Code Playgroud)

但是,当我运行该代码(将第一行更改为(def ^:dynamic *foo* 5))时,不会发生这种情况.我得到三个15s作为输出(使用Clojure 1.4),就像你天真期望的那样 - 也就是说,传递给pmap的函数看到的绑定形式的变化.线程局部绑定和pmap交互的方式有变化吗?我无法在任何地方找到这个记录.

Art*_*ldt 5

从1.3开始,本地绑定集与函数一起发送到pmap.所以只要你标记var ^:dynamic就不再是问题了.此功能称为Binding Conveyance,包含在1.3更改日志中:

来自: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"