`map`

, `filter`

, and `reduce`

express sequence manipulation using compact expressions.

For example, let's sum all primes in an interval .

```
def sum_primes(a, b):
total = 0
x = a
while x < b:
if is_prime(x):
total += x
x += 1
return total
```

This runs in constant space. But what if we wrote instead:

```
def sum_primes(a, b):
return sum(filter(is_prime, range(a, b)))
def is_prime(x):
return x > 1 and all(map(lambda y: x % y, range(2, x)))
```

This also runs in !

Let's write these functions in Scheme. `range`

and `sum`

aren't defined, so we'll define them along with `prime?`

and `sum-primes`

.

```
(define (range a b)
(if (>= a b) nil (cons a (range (+ a 1) b))))
(define (sum s)
(reduce + s))
(define (prime? x)
(and (> x 1)
(null?
(filter (lambda (y) (= 0 (remainder x y)))
(range 2 x)))))
(define (sum-primes a b)
(sum (filter prime? (range a b))))
```

Here, `sum-primes`

doesn't run in constant space. The reason is, unlike Python's `filter`

function, the scheme `filter`

doesn't work lazily. That, along with the fact that we're interpreting Scheme in Python, leads to slower runtime.

A stream is a list, but the rest of the list is only computed when needed (lazy lists).

`(car (cons 1 nil)) --> 1`

`(car (cons-stream 1 nil)) --> 1`

`(cdr (cons 1 nil)) --> ()`

`(cdr-stream (cons-stream 1 nil)) --> ()`

`(cons 1 (cons 2 nil))`

`(cons-stream 1 (cons-stream 2 nil))`

Here, errors only occur when expressions are evaluated.

`(cons 1 (cons (/ 1 0) nil))`

leads to an ==ERROR==.

`(cons-stream 1 (cons-stream (/ 1 0) nil))`

evaluates to `(1 . #[promise (not forced)])`

Let's try this out:

```
(define (range-stream a b)
(if (>= a b) nil (cons-stream a (range-stream (+ a 1) b))))
```

Running `(range 1 1000)`

crashes, but `(range-stream 1 1000)`

is perfectly fine.

Stream ranges are implicit.

A stream of consecutive integers

```
(define (int-stream start)
(cons-stream start (int-stream (+ start 1))))
```

The rest of a constant stream is a constant stream.

`(define ones (cons-stream 1 ones))`

Combine two by separating each into `car`

and `cdr`

:

```
(define (add-streams s t)
(cons-stream (+ (car s) (car t))
(add-streams (cdr-stream s)
(cdr-stream t))))
(define ints (cons-stream 1 (add-streams ones ints)))
```

For any prime , any larger prime must not be divisible by .

The stream of integers not divisible by any is:

- The stream of integers not divisible by any ,
- Filtered to remove any element divisible by .

This recurrence is called the Sieve of Eratosthenes.

```
(define (sieve s)
(cons-stream
(car s)
(sieve (filter-stream
(lambda (x) (< 0 (remainder x (car s))))
(cdr-stream s)))))
```