Clojure:懒惰的魔法

Gab*_*iMe 11 clojure lazy-evaluation lazy-sequences

几乎有2个相同的程序可以生成无限懒惰的random序列.第一个不会崩溃.第二次崩溃与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))
Run Code Online (Sandbox Code Playgroud)

但是下面的崩溃很快:

;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)
Run Code Online (Sandbox Code Playgroud)

Ale*_*ard 22

我相信这是"抓住头脑"的一个例子.

通过在第二个例子中创建引用r1,你可以打开后来说出这样的东西的可能性,(first r1)你将最终存储你的lazy-seq的成员,因为它们被确定.

在第一种情况下,Clojure可以确定无限序列的早期成员将不会做任何事情,因此可以将它们丢弃并且不消耗内存.

我自己仍然是一个Clojure初学者,对我的理解或术语的任何评论或更正都非常感激.

  • 没有堆栈溢出,因为延迟评估不会递归堆栈.评估每个元素并返回. (3认同)
  • 顺便说一句,怎么没有StackOverflow.inf-rand中存在无限递归 (2认同)