`binding` 是否与 `iterate` 一起使用?

Does `binding` works with `iterate`?

代码有什么问题吗?看起来 binding 不适用于 iterate?

(def ^:dynamic *step* 1)

(defn incr [n] (+ n *step*))

(take 3 (binding [*step* 2] (iterate incr 1)))

给予

'(1 2 3)

没有

'(1 3 5)

问题是 iterate returns 一个惰性序列。因此,当您尝试打印序列时,对 incr 函数的第一次调用发生在 binding 范围之外。

从技术上讲,您的 incr 函数并非没有副作用,只是因为它使用了 ^:dynamic 变量。

如果您想将 binding 与惰性序列一起使用,您应该强制在 binding 范围内的某处评估您的序列,例如:

(binding [*step* 2]
  (doall (take 3 (iterate incr 1))))
; => (1 3 5)