In Clojure programming language, why this code passes with flying colors?
(let [r (range 1e9)] [(first r) (last r)])
While this one fails:
(let [r (range 1e9)] [(last r) (first r)])
I know it is about "Losing your head" advice but would you please explain it to me? I'm not able to digest it yet.
UPDATE:
It is really hard to pick the correct answer, two answers are amazingly informative.
Note: Code snippets are from "The Joy of Clojure".
range
generates elements as needed.
In the case of (let [r (range 1e9)] [(first r) (last r)])
, it grabs the first element (0), then generates a billion - 2 elements, throwing them out as it goes, and then grabs the last element (999,999,999). It never has any need to keep any part of the sequence around.
In the case of (let [r (range 1e9)] [(last r) (first r)])
, it generates a billion elements in order to be able to evaluate (last r)
, but it also has to hold on to the beginning of the list it's generating in order to later evaluate (first r)
. So it's not able to throw anything away as it goes, and (I presume) runs out of memory.