2009-11-18 6 views
11

Почти две идентичные программы для создания бесконечных ленивых секретов рандомов. Первый не падает. Второй сбой с исключением OutOfMemoryError. Зачем?Clojure: lazy magic

;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) 

ответ

23

Я считаю, что это пример «держась за головой».

Сделав ссылку r1 во втором примере, вы откроете возможность позже сказать что-то вроде (first r1), чтобы вы в конечном итоге сохранили членов вашего ленивого seq по мере их обновления.

В первом случае Clojure может определить, что с более ранними членами бесконечной последовательности ничего не будет сделано, чтобы их можно было утилизировать и не потреблять память.

Я все еще очень начинающий Clojure, любые комментарии или исправления в моем понимании или терминологии очень ценятся.

+0

Я тоже новичок, но ваше объяснение выглядит очень правильным. Я бы ответил на одно и то же, если бы вы не избили меня! И, по-видимому, согласны с вами 6 активистов. –

+0

Когда я начал делать проблемы Project Euler в Clojure некоторое время назад, мои отладочные отпечатки на бесконечных ленивых последовательностях замедляли мои программы ... бесконечно. Бесконечные ленивые последовательности - важная концепция Clojure, с которой можно справиться. –

+2

Кстати, как нет StackOverflow. Существует бесконечная рекурсия в inf-rand – GabiMe