2009-11-18 10 views
11

Fast 2 identische Programme, um unendliche Lazy Seqs von Randoms zu generieren. Der erste stürzt nicht ab. Der zweite Absturz mit OutOfMemoryError-Ausnahme. Warum?Clojure: faule Magie

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

Aber der folgende Crash ziemlich schnell:

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

Antwort

23

Ich glaube, dies ist ein Beispiel für "auf den Kopf halten".

Indem Sie den Verweis r1 im zweiten Beispiel machen, öffnen Sie die Möglichkeit, später etwas wie (first r1) zu sagen, so dass Sie am Ende die Mitglieder Ihres Lazy-Seq speichern, da sie verdinglicht sind.

Im ersten Fall kann Clojure feststellen, dass mit früheren Mitgliedern der unendlichen Sequenz niemals etwas gemacht wird, damit sie entsorgt werden können und keinen Speicher verbrauchen.

Ich bin immer noch sehr ein Clojure Anfänger selbst, Kommentare oder Korrekturen zu meinem Verständnis oder Terminologie sehr geschätzt.

+0

Ich bin auch ein Anfänger, aber Ihre Erklärung sieht sehr korrekt aus. Ich hätte dasselbe geantwortet, wenn du mich nicht dazu geschlagen hättest! Und 6 Hochwähler scheinen Ihnen zuzustimmen. –

+0

Als ich vor einiger Zeit damit begonnen habe, Probleme mit dem Projekt Euler in Clojure zu lösen, haben meine Debug-Prints auf unendlich faulen Sequenzen meine Programme verlangsamt ... unendlich. Unendliche Lazy-Sequenzen sind ein wichtiges Clojure-Konzept, mit dem man sich auseinandersetzen muss. –

+2

BTW, wie kommt es, dass es keinen StackOverflow gibt. Es gibt eine unendliche Rekursion in inf-rand – GabiMe