GNU Info

Info Node: (librep.info)Local Variables

(librep.info)Local Variables


Next: Setting Variables Up: Variables
Enter node , (file) or (file)node

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))))))
              ...


automatically generated by info2www version 1.2.2.9