the documentation of lazy-seq says:
(lazy-seq & body)
Takes a body of expressions that returns an ISeq or nil, and yields
a Seqable object that will invoke the body only the first time seq
is called, and will cache the result and return it on all subsequent
seq calls. See also - realized?
To illustrate in an example below to calculate the Fibonacci series. We utilize this lazy-seq function.
(defn fibs2_sq [a b] (cons a (lazy-seq (fibs2_impl b (+ a b)))))
(fibs2_sq 0 1)
The output is something like (assuming you run (set! *print-length* 10) to limit the length of values being printed):
(0 1 1 2 3 5 8 13 21 34 55 89 ...)
This look normal, but what if we remove the invocation of lazy-seq function, and run below code:
(defn fibs_sq [a b] (cons a (fibs_sq b (+ a b))))
(take 10 (fibs_sq 0 1))
You will first hit an error saying:
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
After change the second expression to
(take 10 (fibs_sq 0N 1N))
You still hit below error:
StackOverflowError java.math.BigInteger.add (BigInteger.java:1048)
The implication is that lazy-seq only runs the code it wraps when needed. Otherwise, you run into an infinite loop, trying to produce an infinite sequence.