Local Variables
---------------
A "local variable" is a variable which has a temporary value. For
example, when a function is called the variables which are the names of
its arguments are temporarily bound to the values of the arguments
passed to the function. When the function call exits its arguments are
unbound and the previous definitions of the variables come back into
view.
A "binding" is a particular instance of a local variable. Even if a
variable has more than one binding currently in place, only the most
recent is available--there is no way the previous binding can be
accessed until the previous binding is removed.
One way of visualising variable binding is to think of each variable
as a stack. When the variable is bound to, a new value is pushed onto
the stack, when it is unbound the top of the stack is popped. Similarly
when the stack is empty the value of the variable is void (Note:Void
Variables). Assigning a value to the variable (Note:Setting
Variables) overwrites the top value on the stack with a new value.
When the value of the variable is required it is simply read from the
top of the stack.
Apart from function applications there are two special forms which
perform variable binding (i.e. creating local variables), `let' and
`let*'.
- Macro: let bindings body-forms...
`let' creates new variable bindings as specified by the BINDINGS
argument, then evaluates the BODY-FORMS in order. The bindings
are then removed, returning all variables to their state before
the `let' statement was entered. The value of the statement is the
value of the implicit `progn'.
The BINDINGS argument is a list of the bindings to perform. Each
binding is either a symbol, in which case that variable is bound to
`()', or a list whose car is a symbol. The cdr of this list is a
list of forms which, when evaluated as a `progn', gives the value
to bind to that variable.
(setq foo 42)
=> 42
(let
((foo (+ 1 2))
bar)
;; Body forms
(setq foo (1+ foo)) ;This sets the new binding
(cons foo bar))
=> (4 . ())
foo
=> 42 ;The original values is back
No bindings are made until all new values have been computed. For
example:
(setq foo 42)
=> 42
(let
((foo 100)
(bar foo))
(cons foo bar))
=> (100 . 42)
Although `foo' is given a new binding this is not actually done
until all the new values have been computed, hence `bar' is bound
to the _old_ value of `foo'.
- Macro: let* bindings body-forms...
This special form is exactly the same as `let' except for one
important difference: the new bindings are installed _as they are
computed_.
You can see the difference by comparing the following example with
the last example in the `let' documentation (above),
(setq foo 42)
=> 42
(let* ;Using `let*' this time
((foo 100)
(bar foo))
(cons foo bar))
=> (100 . 100)
By the time the new value of `bar' is computed the new binding of
`foo' is already active.
- Macro: letrec bindings body-forms...
`letrec' is similar to `let' and `let*', with the differerence
being that the values of bindings are evaluated with all other
bindings in scope. This means that recursive functions may be
defined with `letrec'. For example, a local factorial function
(from SICP):
(letrec ((fact
(lambda (n)
(if (= n 1)
1
(* n (fact (1- n)))))))
(fact 10))
Note also that letrec allows groups of mutually recursive
functions to be defined, as in the following example (also from
SICP):
(defun f (x)
(letrec ((evenp
(lambda (n)
(if (= n 0)
t
(oddp (1- n)))))
(oddp
(lambda (n)
(if (= n 0)
nil
(evenp (1- n))))))
...