clojure rest 和 next 相关

标签 clojure lazy-evaluation lazy-sequences

我正在关注 Clojure 的乐趣,我对这两个陈述感到困惑

(def very-lazy (-> (iterate #(do (print \.) (inc %)) 1) rest rest rest))

(def less-lazy (-> (iterate #(do (print \.) (inc %)) 1) next next next))

因此,输出是
(println (first very-lazy)) ; .4

(println (first less-lazy)) ; 4

这本书继续解释说

Grabbing the first element in a lazy seq built with rest causes a realization as expected. But the same doesn’t happen for a seq built with next because it’s already been previously realized. Using next causes a lazy seq to be one element less lazy, which might not be desired if the cost of realization is expensive.



我迫切的问题是为什么“非常懒惰”有一个额外的点?我的想法是 'print' 会在调用时打印它的参数,不管 nextrest .

谢谢

最佳答案

Print 在这两种情况下实际上做了完全相同的事情,它只打印数字。额外的 . 是由列表中的代码打印的,它恰好与 4 的打印同时发生,因此它最终出现在屏幕上。

额外的点是动态创建的惰性序列的副作用。我会提出一个更详细的例子来澄清这一点:

从两个完全懒惰的相同列表开始:

esc.core=> (def a (iterate #(do (print "making new element") (inc %)) 1)) 
#'esc.core/a
esc.core=> (def b (iterate #(do (print "making new element") (inc %)) 1))
#'esc.core/b

然后创建两个相同的列表,分别从 ab 的第四个元素开始
esc.core=> (def a-partially-realized (-> a rest rest rest))
making new elementmaking new element#'esc.core/a-partially-realised
esc.core=> (def b-more-fully-realized (-> b next next next))
making new elementmaking new elementmaking new element#'esc.core/b-more-fully-realised
esc.core=> 
a-partially-realized的前三个元素已经被预先计算
b-more-fully-realized 的前四个元素已被预先计算。

当我们读取 a-partially-realized 的第一个元素(原始列表中的第四个)时,它还没有被计算出来,所以我们会看到它正在被计算。
esc.core=> (print (first a-partially-realized))
making new element4nil

当我们对 b-more-fully-realised 做同样的事情时,它已经缓存了值,所以我们立即得到结果。
esc.core=> (print (first b-more-fully-realized))
4nil

关于clojure rest 和 next 相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7970314/

相关文章:

lisp - Lisp 中的 1 和 '1 有什么区别?

python - 当依赖项更改时, 'intelligently' 在 Python 中重置记忆化属性值的最佳方法

haskell - Haskell 在惰性求值期间会丢弃中间结果吗?

javascript - Immutable.js - 惰性序列

clojure - 非线性减速在 Clojure 中创建惰性序列

clojure - 在 LightTable 中运行 leiningen Clojure 项目

swing - Clojure 的跷跷板 : How do I recognize that enter has been pressed

clojure - 如何在 Clojure 中取消定义函数?

ocaml - 流(又名 "lazy lists")和尾递归

r - 如何在 dplyr 中进行功能重命名?