I believe the problem is that with each repetition you create a new lazy sequence related to the last one, so after several iterations you hold the section that holds the head of seq, which holds the head of seq, which holds the head of seq .... All intermediate sections fill your heap.
Although writing a simple sieve is a useful exercise if you want an answer, Clojure includes a sequence of primes in the standard library: clojure.contrib.lazy-seqs / primes. The standard solution to this given Euler problem is one-line.
As a style point, internal defn is not a good idea. The practical effect is the same as if defn were at the top level, but if I'm not mistaken, var gets reassigned every time getAllPrimes is called, and overriding vars at runtime is highly discouraged. Because the code simply defines var, getPrimes is still as visible as getAllPrimes. In this case, getPrimes can easily be rewritten as a / recur loop without an internal function, anonymous or named. This does not help to solve the problem with the lazy-seqs chain, but makes the code more standard:
(defn getAllPrimes [lim] (loop [primes () numlist (range 2 lim)] (if (not-empty numlist) (recur (cons (first numlist) primes) (filter (fn [x] (not (div? x (first numlist)))) (rest numlist))) primes)))
I would also avoid using camelCase. The default Clojure name for this function would be get-all-primes.
Returning to the practical problem, however, the least work you could do to get your code to work was to get each section to go through each iteration, i.e. wrap filter call in doall. I tried this, and while it still runs slowly, it at least ends without ending the heap:
(defn get-all-primes [lim] (loop [primes () numlist (range 2 lim)] (if (not-empty numlist) (recur (cons (first numlist) primes) (doall (filter
dreish
source share