In using ` sum` as in section 1.3.1, it seems
terribly awkward to have to define trivial procedures such as `
pi-term` and ` pi-next` just so we can use them as
arguments to our higher-order procedure. Rather than define `
pi-next` and ` pi-term`, it would be more convenient to
have a way to directly specify "the procedure that returns its input
incremented by 4" and "the procedure that returns the reciprocal of
its input times its input plus 2." We can do this by introducing the
special form ` lambda`, which creates procedures. Using `
lambda` we can describe what we want as

`
(lambda (x) (+ x 4)
`

`
`
and

`
(lambda (x) (/ 1.0 ( x (+ x 2))))
`

Then our ` pi-sum` procedure can be expressed without defining any
auxiliary procedures as

Again using(define (pi-sum a b) (sum (lambda (x) (/ 1.0 ( x (+ x 2)))) a (lambda (x) (+ x 4)) b))

In general,(define (integral f a b dx) ( (sum f (+ a (/ dx 2.0)) (lambda (x) (+ x dx)) b) dx))

`
(lambda ( _{}) _{})
`

The resulting procedure is just as much a procedure as one that is
created using ` define`. The only difference is that it has not
been associated with any name in the environment. In fact,

`
(define (plus4 x) (+ x 4))
`

is equivalent to

`
(define plus4 (lambda (x) (+ x 4)))
`

We can read a ` lambda` expression as follows:

Like any expression that has a procedure as its value, a `
lambda` expression can be used as the operator in a combination
such as

`
((lambda (x y z) (+ x y (square z))) 1 2 3)
12
`

or, more generally, in any context where we would normally use a
procedure name.^{53}

**Using let to create local variables**

Another use of ` lambda` is in creating local variables. We
often need local variables in our procedures other than those that
have been bound as formal parameters. For example, suppose we wish to
compute the function

*f (x,y) = x (1 + wy)*^{2}* + y (1 - y) + (1 + xy) (1 - y)*

which we could also express as

In writing a procedure to compute *f*, we would like to include
as local variables not only *x* and *y* but also the
names of intermediate quantities like *a* and *b*. One
way to accomplish this is to use an auxiliary procedure to bind the
local variables:

Of course, we could use a(define (f x y) (define (f-helper a b) (+ ( x (square a)) ( y b) ( a b))) (f-helper (+ 1 ( x y)) (- 1 y)))

This construct is so useful that there is a special form called(define (f x y) ((lambda (a b) (+ ( (square a)) ( y b) ( a b))) (+ 1 ( x y)) (- 1 y)))

The general form of a(define (f x y) (let ((a (+ 1 ( x y))) (b (- 1 y))) (+ ( x (square a)) ( y b) ( a b))))

which can be thought of as saying(let ((_{ }) (_{ }) . . . (_{ }))_{})

let

_{} have the value _{} and

_{} have the value _{} and

.

.

.

_{} have the value _{}

in _{}

The first part of the ` let` expression is a list of
name-expression pairs. When the ` let` is evaluated, each name
is associated with the value of the corresponding expression. The
body of the ` let` is evaluated with these names bound as local
variables. The way this happens is that the ` let` expression
is interpreted as an alternate syntax for

No new mechanism is required in the interpreter in order to provide local variables. A((lambda (_{}..._{})_{})_{}. . ._{})

We can see from this equivalence that the scope of a variable
specified by a ` let` expression is the body of the `
let`.
This implies that:

is 38. Here, the(+ (let ((x 3)) (+ x ( x 10))) x)

will have the value 12 because, inside the body of the(let ((x 3) (y (+ x 2))) ( x y))

Sometimes we can use internal definitions to get the same effect as
with ` let`. For example, we could have defined the procedure
` f` above as

We prefer, however, to use(define (f x y) (define a (+ 1 ( x y))) (define b (- 1 y)) (+ ( x (squre a)) ( y b) ( a b)))

**Exercise 1.34**

Suppose we define the procedure

Then we have(define (f g) (g 2))

`
(f square)
4
`

`
(f (lambda (z) ( z (+ z 1))))
6`

What happens if we (perversely) ask the interpreter to evalutate the
combination `(f f)`? Explain.