Welcome! Please see the About page for a little more info on how this works.

0 votes
in Sequences by

Hello, I am new to Clojure and to lazy sequences.

(defn get-biggest-prime-factor [num]
  (let [max-check (inc (Math/sqrt num))
        lazy-primes (filter-lazy-seq is_prime naturals)]
    (loop [prime (first lazy-primes)
           max-factor 1]
      (cond (>= prime max-check) max-factor
            (= 0 (rem num prime)) (recur (first (rest lazy-primes)) (first lazy-primes))
            :else (recur (first (rest lazy-primes)) max-factor)))) )
  • naturals is an infinite lazy sequence of 1,2,3 ... ,
  • filter-lazy-seq is a function, which returns a lazy sequence derived from second argument. Every element of sequence is verified by first argument, which is a predicate
  • is-prime is a function that check if a number is prime

Any help is appreciated.

can you provide the rest of the code?
edited by
Of course,

(defn is_prime [num]
  (letfn [(helper [i]
              (> i (Math/sqrt num)) true
              (= 0 (rem num i)) false
              :else (recur (inc i))))]
    (helper 2)))

;returns a lazy sequence, every next element of which is filtered by a predicate
(defn filter-lazy-seq [predicate sequence]
  (cond (= sequence  nil) nil
        (predicate (first sequence))
        (cons (first sequence) (lazy-seq (filter-lazy-seq predicate
                                                          (rest sequence))))
        :else (filter-lazy-seq predicate (rest sequence))))

(defn natural-gen []
  (letfn [(helper [n]
            (cons n (lazy-seq (helper2 (inc n)))))]
    (helper 1))

(def naturals (natural-gen))

1 Answer

+1 vote
selected by
Best answer

I suspect your problem is that you are "holding onto the head" -- your function binds lazy-primes to the sequence and then you walk down the sequence so you still have a reference to the entire sequence, and if you ask for a large enough num, you are going to exceed the heap since your function needs the entire sequence to work.

So, the evaluation continues until the memory overflows even when I ask for little numbers (i. e. (get-biggest-prime-factor 6)). I have provided the rest of the code in the question comments section.
Now I see all the code and tried it in a REPL, I can see the problem:

In get-biggest-prime-factor, when you recur, you pass (first (rest lazy-primes)) but lazy-primes doesn't change in the loop so you always pass 2 so it repeatedly checks the same values.

Also, in one recur, you are passing (first lazy-primes) as max-factor -- which, again, will never change.
Thank you so much!!!