Previous Next Contents

11. Binding

Binding is lexically scoped assignment. It happens to the variables in a function's parameter list whenever the function is called: the formal parameters are bound to the actual parameters for the duration of the function call. You can bind variables anywhere in a program with the let special form, which looks like this:

(let ((var1 val1)
      (var2 val2)
      ...
     )
    body)

(It's considered bad style to leave a single ``)'' on a line)

Let binds var1 to val1, var2 to val2, and so forth; then it executes the statements in its body. The body of a let follows exactly the same rules that a function body does. Some examples:

> (let ((a 3)) (+ a 1))
4
> (let ((a 2) 
        (b 3)
        (c 0))
    (setq c (+ a b))
    c)
5
> (setq c 4)
4                     ;and a warning from CMUCL, ignore it    
> (let ((c 5)) c)
5
> c
4

Instead of (let ((a nil) (b nil)) ...), you can write (let (a b) ...).

The val1, val2, etc. inside a let cannot reference the variables var1, var2, etc. that the let is binding. For example,

> (let ((x 1)
        (y (+ x 1)))
    y)
Error: Attempt to take the value of the unbound symbol X
                      ;in CMUCL:

In: LET ((X 1) (Y (+ X 1)))
  (LET ((X 1) (Y #))
    Y)
Warning: Variable X defined but never used.


Warning: This variable is undefined:
  X

Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable X is
unbound.

Restarts:
  0: [ABORT] Return to Top-Level.

Debug  (type H for help)

(EVAL::LEAF-VALUE
 #<C::REF #x9009B15  LEAF= #<C::GLOBAL-VAR #x9009AD5  NAME= X  KIND=
 :GLOBAL>>
 0
 #())
0]

If the symbol x already has a global value, stranger happenings will result:

> (setq x 7)
7                     ;again a warning in CMUCL:
Warning:  Declaring X special.
                      ;x is automaticly declared special
> (let ((x 1)
        (y (+ x 1)))
    y
  )
8

The let* special form is just like let except that it allows values to reference variables defined earlier in the let*. For example,

> (setq x 7)
7
> (let* ((x 1)
         (y (+ x 1)))
    y
  )
2

The form

(let* ((x a)
       (y b))
       ...
) 

is equivalent to

(let ((x a))
     (let ((y b))
          ...
) )


Previous Next Contents