A stream reveals only the part you demand.
A stream keeps its first value now and delays the computation that can produce the rest of the sequence.
How can a finite run use a sequence with no final element?
- Read a stream as a present value and a delayed tail
- Follow demand through repeated stream-ref calls
- Distinguish describing an infinite process from executing forever
integers-from can describe an unending sequence because cons-stream does not evaluate its tail immediately. Each tail is a promise for the next pair.
stream-ref forces exactly as many tails as it needs to reach the requested index. Asking for index 9 constructs a finite prefix and returns 10, so this particular run terminates.
(letrec ((integers-from
(lambda (n)
(cons-stream n (integers-from (+ n 1)))))
(stream-ref
(lambda (stream n)
(if (= n 0)
(car stream)
(stream-ref (force (cdr stream)) (- n 1))))))
(stream-ref (integers-from 1) 9))- Output
- —
- Value
- —
- Diagnostic
- —
The first program returns 10 after forcing nine stream tails.
Find the repeated force events. Each computed outcome exposes one more pair, while the unrequested remainder stays delayed.
Change the program before you read the hint.
Change the requested index from 9 to 4. Predict the value and how many stream tails must be forced.
Show one hint
Index 0 uses the current car without forcing the cdr.