15-150: Principles of Functional Programming

Lecture 20: Streams : Lazy, Demand-Driven Computation

Functions in SML are evaluated eagerly, meaning that the arguments are reduced before the function is applied. An alternative is for function applications and constructors to be evaluated in a lazy manner, meaning expressions are evaluated only when their values are needed in a further computation. Lazy evaluation can be implemented by "suspending" computations in function values, also known as "thunks", a form of "encapsulated computation". This style of evaluation is useful when working with potentially infinite data structures, such as streams, which arise naturally in many applications. Streams may be thought of as lazy lists, potentially without a base case, whose elements are determined by suspended computations that generate the next element of the stream only when forced to do so.

We introduced some basic stream functions.

We created a stream containing all the prime numbers, inspired by the Sieve of Eratosthenes.

Key Concepts

Sample Code

Some notes on lazy evaluation

The sieve code for computing the primes from class illustrates lazy programming. It does compute all the primes (lazily). It is however not a faithful transcription of the sieve.
The following paper by Melissa O'Neill discusses the differences and provides a functional implementation of the actual sieve:
The Genuine Sieve of Eratosthenes

Slides from Lecture