If nested let
s define variables by the same name, then the
uses of that name in the body of the inner let
will refer to the
bindings created by the inner let
.
Consider the following code fragment:
(let ((x 10) ; outer binding of x (a 20)) ; binding of a (foo x) (let ((x (bar)) ; inner binding of x (b (baz x x))) ; binding of b (quux x a) (quux y b)) (baz x a) ; refers to outer x (and a) (baz x b)) ; illegal?
When control enters the outer let
, the initial values for the
variables are computed. In this case, that's just the literal values
10
and 20
. Then storage is allocated for the variables,
and initialized with those values. Once that's done, the meaning of
the names x
and a
changes--they now refer to the new
storage for (bindings of) the let
variables x
and
a
---and then the body expressions are evaluated.
Similarly, when control enters the inner let
, the inital values
are computed by the calls to bar
and baz
, and then
storage for x
and b
is allocated and initialized with
those values. Then the meanings of the names x
and b
change, to refer to the new storage (bindings) of those variables.
(For example, the value of x
when (baz x x)
is evaluated
is still 10, because x
still refers to the outer x
.)
In this example, the meaning of the identifier x
changes when
we enter the inner let
. We say that the inner let variable
x
shadows the outer one, within the body of the let
.
The outer x
is no longer visible, because the inner one is.
When we exit a let
(after evaluating its body expressions), the
bindings introduced by the let
"go out of scope," i.e., aren't visible
anymore. (For example, when we evaluate the expression (baz x a)
in the body of the outer let
, x
refers to the binding
introduced by the outer let
---the x
introduced by the
inner let is no longer visible.
Likewise, in the example code fragment, the b
in the last
expression, (baz x b)
, does not refer to the inner let
's
binding of b
. Unless there is a binding of b
in some
outer scope we haven't shown (such as a top-level binding), then
this will be an error.