From SICP section
1.3.1 Procedures as ArgumentsExercise 1.31 asks us to write a
product procedure (analogous to
sum) that computes the product of a function at points over a given range. We need to show how to define
factorial in terms of the new
product procedure, and use
product to compute approximations to π using the following formula:

Finally, if our
product procedure is recursive, we need to write an iterative version, and vice versa.
Since summing a series and multiplying a series are extremely similar ideas, it's not surprising to find that it's very simple to modify
sum to produce
product. Let's use the recursive version from
exercise 1.29 first.
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
The
product procedure really only needs to perform a different operation and end on a different value than
sum. The last step (when a > b) should be to multiply by 1 instead of adding 0.
(define (product term a next b)
(if (> a b)
1
(* (term a)
(product term (next a) next b))))
We can test this out by implementing
factorial in terms of
product using the
identity and
inc procedures that we've used before.
(define (identity x) x)
(define (inc x) (+ x 1))
(define (factorial x)
(product identity 1 inc x))
> (factorial 3)
6
> (factorial 4)
24
> (factorial 5)
120
> (factorial 10)
3628800
> (factorial 20)
2432902008176640000
The next test is to approximate π using something called
Wallis' product or the
Wallis Formula. (Lucky for us that mathematicians have already expressed this as the product of a series, saving us the work of coming up with a function for generating the terms.)

We'll multiply the product on the right hand side by the denominator on the left hand side so our procedure will just approximate π directly.
(define (wallis-pi n)
(define (term x)
(/ (* 4.0 (square x))
(- (* 4.0 (square x)) 1)))
(* 2.0 (product term 1 inc n)))
> (wallis-pi 10)
3.0677038066434994
> (wallis-pi 100)
3.133787490628163
> (wallis-pi 1000)
3.1408077460304042
> (wallis-pi 10000)
3.1415141186819313
Since our
product procedure is implemented recursively, we need to show an iterative version. We can go back to the iterative
sum procedure for inspiration.
(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (+ (term a) result))))
(iter a 0))
Again, there are very few changes required to transform this procedure.
(define (product-iter term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* (term a) result))))
(iter a 1))
You can plug
product-iter into the
factorial and
wallis-pi procedures above to verify that they give the same results.
The similarities between our two versions of
sum and
product is no accident. This section of SICP is all about higher-order procedures, so in the next exercise we're going to see how pull the similarities out of these procedures into something even more abstract.
Related:For links to all of the SICP lecture notes and exercises that I've done so far, see
The SICP Challenge.