反复与绑定

repeatedly vs. binding

(def ^:dynamic *d* 1)

(binding [*d* 2]
  (println *d*)
  (repeatedly 1 #(println *d*)))

输出:

2
1

为什么?为什么 repeatedly 内部的函数从 binding 外部看到动态变量的值?

对了,我检查了(.getId (java.lang.Thread/currentThread))匿名函数内外:是一样的

repeatedly创建的惰性序列从表单返回,然后通过REPL打印时才实现,绑定后"unwound,"此时匿名正在调用函数。要查看情况是否如此,请尝试以下两种变体:

(binding [*d* 2]
  (println *d*)
  (let [x (repeatedly 1 #(println *d*))]
    (println (realized? x))
    x))

(binding [*d* 2]
  (println *d*)
  (doall (repeatedly 1 #(println *d*))))

第二个变体强制序列完全实现,同时仍在绑定范围内。

请注意,另一种解决问题的方法是 "capture" 使用 bound-fn:

进行绑定
(binding [*d* 2]
  (println *d*)
  (repeatedly 1 (bound-fn [] (println *d*))))