On problem 3 of the euler project I tried this:
(defn range-start-2 [] (map #(+ % 2) (range)))
(defn largest-prime
"Finds the largest prime factor of n. (n must be >= 2)"
[n largest-prime unchecked]
(cond
(> (first unchecked) n)
largest-prime
(= (mod n (first unchecked)) 0)
(recur n (first unchecked) (filter #(not= (mod % (first unchecked)) 0) unchecked))
:else
(recur n largest-prime (filter #(not= (mod % (first unchecked)) 0) unchecked))))
(largest-prime (* 3 7 11 13) 2 (range-start-2))
;=> 13
This works for small n but gives me a stack overflow for larger n. I assume that I'm holding on to the head of the unchecked seq, but I can't figure out where. Using it as a parameter shouldn't hold onto the head, should it?
I read that closing over a lazy-seq could cause the head to be held, so I tried this:
(defn largest-prime
"Finds the largest prime factor of n."
[n largest-prime unchecked]
(let [prime (first unchecked)]
(cond
(> prime n)
largest-prime
(= (mod n prime) 0)
(recur n prime (filter #(not= (mod % prime) 0) unchecked))
:else
(recur n largest-prime (filter #(not= (mod % prime) 0) unchecked)))))
This doesn't work either. There has to be a way to get the value of the first element of a lazy-seq without holding on to it's head.
(Of course there are better ways to solve the euler project problem, but here I'm only interested in the head holding issue)