为什么动态绑定会影响 future 的 body?

Why does dynamic binding affect the body of future?

我正在尝试重现 Chas 描述的动态变量的缺陷 - http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/

考虑以下片段:

(def ^:dynamic *dynamic-x* 10)

(defn adder [arg]
  (+ *dynamic-x* arg))

(adder 5) ;; returns 15

(binding [*dynamic-x* 20]
  (adder 5)) ;; returns 25

(binding [*dynamic-x* 20]
  @(future (adder 5))) ;; returns 25 (!)

实际上,我期望第 3 种情况会 return 15,一旦在单独的线程和当前线程本地值 *dynamic-x* 上执行添加(我应该是 10)应该使用。但是,对我来说出乎意料的是,它 returns 25.

我哪里错了?

future 的设计是将动态绑定传递给将执行未来主体的其他线程(查看 future 的源代码,它遵循 future-call,它使用一个名为 binding-conveyor-fn 的函数,该函数显式复制线程局部绑定)。

这个 IMO 的动机是,当使用 future 时,你想 运行 在同一个 "logical thread" 中进行计算,只是你实际上是在另一个 [=22] 中进行计算=] 出于性能原因的线程。

我同意它应该被明确记录:)