Clojure 为什么动态绑定会影响未来的主体?
我试图重现Chas-描述的动态变量的陷阱 考虑以下代码段:Clojure 为什么动态绑定会影响未来的主体?,clojure,future,dynamic-variables,Clojure,Future,Dynamic Variables,我试图重现Chas-描述的动态变量的陷阱 考虑以下代码段: (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 (!)
(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 (!)
实际上,我希望在单独的线程上执行加法后,第三个case将返回15,并且应该使用当前线程的本地值*dynamic-x*
(我认为是10)。但是,出乎意料的是,它返回了25
我错在哪里?这是
future
的设计,动态绑定被传递到其他线程,future主体将在这些线程中执行(查看future
的源代码,它遵从future调用
,它使用一个名为binding converter fn
的函数显式复制线程本地绑定)
这个IMO的动机是,当使用future
时,您希望在同一个“逻辑线程”中运行计算,但出于性能原因,您实际上是在另一个Java线程中运行计算
我同意它应该被明确地记录下来:)你能为这个问题提供一个更好的标题吗?可能类似于
为什么动态绑定会意外地在未来工作
@cfrick是的,当然。实际上,我在想:)注意:Clojure源代码上的断言是从v1.7.0开始的