0

I am confused as to why the code below goes into an infinite loop and does not return a lazy sequence when I am calling lazy-seq:

 (= (take 5 ((fn [func se] 
               (lazy-seq 
                (reduce (fn [acc item] 
                          (conj acc (func (last acc) item)))
                        [(first se)] (rest se)))) 
             + 
             (range)))
     [0 1 3 6 10])

The repl just spins as range gets infinitely called.

How can I make this function behave lazily?

1 Answer 1

2

In order to construct a lazy-sequence you need to return a sequence that is realized as needed.

What you're doing in your function is just wrapping an infinite reduction in a lazy-seq call.

There's a pattern that usually works and is realizing a new element only as needed:

 (lazy-seq
     (cons element (recursion ..

That means if you want to build a lazy reduce you will be doing something along these lines:

 (fn [f s init]
    (lazy-seq
        (let [acc (f (first s) init)]
           (cons acc (recur f (rest s) acc))

In that case your returned sequence will exist in memory as a partially realized sequence

  (0 1 3 (recur + (rest s) 3))

With the remaining elements existing only logically as a to-be-called recursion.

You can have a look at this previous answer explaining the non laziness of reduce.

Sign up to request clarification or add additional context in comments.

4 Comments

Would recur not have the same result as reduce and it will just spin?
No because reduce needs to iterate until the sequence is empty so you can have the final result, the function proposed recurs only as needed. You could have used reductions also
Thanks, I'm trying to recreate reductions to increase my clojure knowledge so it is just for fun
ok, you consider your question answered as why you cannot wrap reduce in a lazy-seq call?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.