Prev Up Next
Local variables can be introduced without explicitly
creating a procedure. The special form `let`
introduces a list of local variables for use within its
body:

(`let` ((**x** *1*)
(**y** *2*)
(**z** *3*))
(**list** **x** **y** **z**))
**=>** (*1* *2* *3*)

As with `lambda`, within the `let`-body, the local
**x** (bound to *1*) shadows the global **x** (which
is bound to *20*).

The local variable initializations -- **x** to *1*;
**y** to *2*; **z** to *3* -- are not considered
part of the `let` body. Therefore, a reference to
**x** in the initialization will refer to the global,
not the local **x**:

(`let` ((**x** *1*)
(**y** **x**))
(**+** **x** **y**))
**=>** *21*

This is because **x** is bound to *1*, and **y** is
bound to the *global* **x**, which is *20*.

Sometimes, it is convenient to have `let`'s list of
lexical variables be introduced in sequence, so that
the initialization of a later variable occurs in the
*lexical scope* of earlier variables. The form
`let*` does this:

(`let*` ((**x** *1*)
(**y** **x**))
(**+** **x** **y**))
**=>** *2*

The **x** in **y**'s initialization refers to the **x**
just above. The example is entirely equivalent to --
and is in fact intended to be a convenient abbreviation
for -- the following program with nested `let`s:

(`let` ((**x** *1*))
(`let` ((**y** **x**))
(**+** **x** **y**)))
**=>** *2*

The values bound to lexical variables can be
procedures:

(`let` ((**cons** (`lambda` (**x** **y**) (**+** **x** **y**))))
(**cons** *1* *2*))
**=>** *3*

Inside this `let` body, the lexical variable **cons**
adds its arguments. Outside, **cons** continues to
create dotted pairs.

Prev Up Next