# 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

- Eager vs. lazy evaluation
- Demand-driven computation
- Encapsulated computation
- Suspensions (aka thunks)
- Streams as potentially infinite lists
- Higher-order stream functions

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