当一个函数给出一个很大的延迟seq时,避免保留头部是有益的,这样如果完全实现的序列不适合内存,你仍然可以处理它.例如,这工作正常:
(count (take 10000000 (range)))
(reduce + (take 10000000 (range)))
Run Code Online (Sandbox Code Playgroud)
但是这会产生内存不足错误:
(defn recount [coll n]
[(count (take n coll))
(reduce + (take n coll))])
(recount (range) 10000000)
Run Code Online (Sandbox Code Playgroud)
因为当计数实现了懒惰的seq时,coll的绑定会保留序列的头部.
我能想出的最接近的东西是一个宏,它强制重新评估seq而不是绑定:
(defmacro recount4 [coll n]
`[(count (take ~n ~coll))
(reduce + (take ~n ~coll))])
(recount4 (range) 10000000)
Run Code Online (Sandbox Code Playgroud)
这似乎没有广泛适用.
我查看了这个博客,但由于原子和可变状态的使用,解决方案不太令人满意.