Lisp variant of the let special form. The syntax is the same:

(let* ((VAR1 EXPR1)
       (VAR2 EXPR2)
       ... )
evaluates BODY with the variables VAR1, VAR2, ... bound to the specified values.

Unlike let, however, which binds all variables simultaneously, let* binds them sequentially. That is, occurrences of VARi in the expressions of a let form all refer to the VARi defined outside the from (or attempt to reference an undefined variable, if there is no variable by that name outside the form). But occurrences of VARi in the expressions EXPRj of a let* form with j>i refer to the VARi defined in that let* form.

Thus, the above form is equivalent to

(let ((VAR1 EXPR1))
  (let ((VAR2 EXPR2))
    (let ...
      ... BODY) ...
or to the corresponding lambda expression
(lambda (VAR1)
  (lambda (VAR2)
    (lambda ...
      ... BODY) ...

Despite seeming easier to use (let* is superficially more like a sequence of assignment statements in C than let, in that later assignments can use the values of earlier assignments), let* is considerably less useful than let. Think of the simultaneous binding of values in let as roughly the same as the simultaneous binding of values in a function call; a let* form has no such convenient representation. In Scheme terms, let creates only one environment, whereas let* creates one for each variable.


let* is useful when we want to compute several values which all require a previous value or values. For example, say we want to print a point's distance to the origin in Emacs Lisp (assume functions get-x and get-y are defined to do the right thing):

(defun pt-show-dist (pt)
  (let* ((x (get-x pt))
         (y (get-y pt))
         (d (sqrt (+ (* x x) (* y y)))))
    (message "Point <%f,%f> is %f away from the origin" x y d)))

Log in or register to write something here or to contact authors.