反复与绑定
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*))))
(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*))))