Lazy Sequences & Infinite Streams
Master Clojure's lazy sequences to model infinite streams, defer computation, and process data efficiently without blowing up memory.
Lazy Sequences & Infinite Streams is a free Clojure Functional Programming & JVM Backend Development lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Clojure Functional Programming & JVM Backend Development learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is Laziness?
A lazy sequence computes its elements only as they are needed. This lets you describe potentially infinite data and consume just the part you want.
An Infinite Range
range with no arguments returns an infinite lazy sequence. It never materializes fully; you take only what you need.
(take 5 (range))
; => (0 1 2 3 4)iterate
iterate builds an infinite sequence by repeatedly applying a function to a starting value.
(take 5 (iterate (fn [x] (* x 2)) 1))
; => (1 2 4 8 16)repeat and cycle
repeat yields the same value forever; cycle loops a collection forever. Both are lazy.
(take 3 (repeat :x)) ; => (:x :x :x)
(take 5 (cycle [1 2])) ; => (1 2 1 2 1)lazy-seq
You build your own lazy sequences with lazy-seq. The body runs only when the next element is requested.
(defn nums-from [n]
(lazy-seq
(cons n (nums-from (inc n)))))
(take 4 (nums-from 10)) ; => (10 11 12 13)Lazy Transformations
map, filter, and take-while are all lazy. Chaining them does no work until you consume the result.
(->> (range)
(map (fn [x] (* x x)))
(filter even?)
(take 4))
; => (0 4 16 36)Realization & Chunking
Lazy seqs are realized in chunks of 32 for efficiency. So asking for one element may compute up to 32. Keep transformations side-effect-free to avoid surprises.
(first (map (fn [x] (println "seen" x) x) (range 100)))
; prints 0..31 due to chunkingForcing Realization
Use doall to fully realize a lazy sequence (e.g. to trigger side effects), or dorun when you do not need the results.
(doall (map println [1 2 3]))Avoiding the Head-Holding Trap
If you keep a reference to the head of an infinite seq while walking it, the whole realized portion stays in memory. Let go of the head to allow garbage collection.
; Bad: binding holds the head
(let [s (range)] (last (take 1000000 s)))Practical Stream: Fibonacci
Lazy sequences elegantly express recursive streams like Fibonacci numbers.
(def fibs
(map first
(iterate (fn [[a b]] [b (+ a b)]) [0 1])))
(take 7 fibs) ; => (0 1 1 2 3 5 8)Laziness vs Transducers
Lazy seqs build intermediate sequences; transducers (from a prior lesson) avoid them. Use laziness for infinite/streamed data and transducers for high-throughput pipelines.
Quick Check
Test your lazy-sequence intuition.
Recap
You learned how lazy sequences defer computation and model infinite streams.
- Generate with
range,iterate,repeat,cycle,lazy-seq map/filterstay lazy until consumed- Beware chunking and head-holding
Frequently asked questions
Is the “Lazy Sequences & Infinite Streams” lesson free?
Yes — the full text of “Lazy Sequences & Infinite Streams” is free to read here on the web, and the Clojure Functional Programming & JVM Backend Development course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Clojure Functional Programming & JVM Backend Development course, upgrade to CoddyKit PRO.
What will I learn in “Lazy Sequences & Infinite Streams”?
Master Clojure's lazy sequences to model infinite streams, defer computation, and process data efficiently without blowing up memory. You practise Clojure Functional Programming & JVM Backend Development with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Clojure Functional Programming & JVM Backend Development?
No prior experience is required. Clojure Functional Programming & JVM Backend Development on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Lazy Sequences & Infinite Streams” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Clojure Functional Programming & JVM Backend Development lesson?
Yes. Every Clojure Functional Programming & JVM Backend Development lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Transducers for Efficient Processing
- Monads & Functional Abstractions
- Property-Based Testing with clojure.test.check
- Lazy Sequences & Infinite Streams