liveBook · Manning

Infinite data structure

As explained in Clojure: The Essential Reference

An infinite sequence is a sequence with unboundedly many elements, typically generated on demand.

An infinite sequence supplies values to sequence-processing operations without requiring a predetermined endpoint. In Clojure, lazy generators make this useful for number streams, evolving states, and work created on demand. Consume only the portion needed, for example with take or a stopping condition. section 9.2.2 section 9.2.1

Choose a generator according to how each value is produced:

  • (range) yields an unbounded sequence of increasing numbers starting at 0; an end argument makes it finite. section 3.4.2
  • (iterate f x) yields x, then (f x), then (f (f x)), and so on. Use it when each state determines the next; f should be free of side effects. section 9.2.2
  • (repeatedly f) calls a no-argument function for each value, making it suitable for random values or other side-effecting work. (repeatedly n f) stops after n calls. section 9.2.1
  • (repeat x) supplies the same value repeatedly, such as zeroes used as defaults. When mapped alongside a finite argument sequence, processing stops at the shorter sequence. section 2.2.1

Take a finite view

(take 10 (iterate inc 0)) ;; (0 1 2 3 4 5 6 7 8 9) The source remains unbounded; take requests ten values. section 9.2.2

Carry state between values

(def fibo (iterate (fn [[x y]] [y (+' x y)]) [0 1])) (take 10 (map first fibo)) ;; (0 1 1 2 3 5 8 13 21 34) Each pair carries the information needed to calculate the next one. The same pattern can produce successive Game of Life states. section 9.2.2

Laziness does not make every use memory-safe. Retaining a reference to the start of a large realized range or repeatedly-generated sequence can exhaust memory. Keep consumption bounded, and avoid holding the head when only later values are needed. section 3.4.2 section 9.2.1

How Clojure: The Essential Reference covers it

How deep it goes
Defines generator contracts and exceptions, works through stateful examples, and demonstrates memory and performance consequences of laziness.
Examples
Demonstrates Fibonacci pairs, a pi approximation, Game of Life states, random values, and lazy worker batches.
What you can do after
Build it from scratch with lazy-seq and cons, or apply it via iterate to generate and consume successive states.
How it connects
Connects lazy sequences with iterate, range, map, transduce, and state progression.

Also explained in

Compare how 2 books explain infinite data structure →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.