Clojure:懒惰的魔法

11
几乎相同的程序生成无限的惰性随机序列。第一个不会崩溃,第二个会因为OutOfMemoryError异常而崩溃。为什么?
;Return infinite lazy sequence of random numbers    
(defn inf-rand[] (lazy-seq (cons (rand) (inf-rand))))    

;Never returns. Burns the CPU but won't crash and lives forever.    
(last (inf-rand))

但是以下内容很快就会崩溃:
;Return infinite lazy sequence of random numbers    
(defn inf-rand[] (lazy-seq (cons (rand) (inf-rand))))    
(def r1 (inf-rand))

;Crash with "OutOfMemoryError"
 (last r1)
1个回答

22

我相信这是“持有头部”的一个例子。

在第二个例子中,通过将引用r1标记出来,您打开了以后可能会说类似于(first r1)的可能性,因此您最终将按照它们被实现的方式存储惰性序列的成员。

在第一种情况下,Clojure可以确定永远不会使用无限序列的早期成员,因此它们可以被处理并且不会消耗内存。

我仍然是一个Clojure初学者,欢迎任何对我的理解或术语的评论或更正。


我也是个初学者,但你的解释看起来非常正确。如果你没有先我回答的话,我也会给出同样的答案!而且有6个点赞者似乎也同意你的观点。 - Carl Smotricz
前段时间我开始用Clojure解决Project Euler的问题,我的无限惰性序列调试输出使程序无限变慢了。无限惰性序列是一个重要的Clojure概念,需要深入理解。 - Carl Smotricz
2
顺便问一下,为什么没有 StackOverflow。inf-rand 中存在无限递归。 - GabiMe
3
由于惰性求值不会在堆栈上递归,因此不存在堆栈溢出问题。每个元素都会被评估并返回结果。 - Eric Normand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接