#### 4.2.2 Binding constructs

The three binding constructs ‘`let`’, ‘`let*`’, and ‘`letrec`’ give Scheme a block structure, like Algol 60. The syntax of the three constructs is identical, but they differ in the regions they establish for their variable bindings. In a ‘`let`’ expression, the initial values are computed before any of the variables become bound; in a ‘`let*`’ expression, the bindings and evaluations are performed sequentially; while in a ‘`letrec`’ expression, all the bindings are in effect while their initial values are being computed, thus allowing mutually recursive definitions.

— library syntax: let <bindings> <body>

> Syntax: <Bindings> should have the form

>     ((<variable1> <init1>) ...),

> where each <init> is an expression, and <body> should be a sequence of one or more expressions. It is an error for a <variable> to appear more than once in the list of variables being bound.

> Semantics: The <init>s are evaluated in the current environment (in some unspecified order), the <variable>s are bound to fresh locations holding the results, the <body> is evaluated in the extended environment, and the value(s) of the last expression of <body> is(are) returned. Each binding of a <variable> has <body> as its region.

>     (let ((x 2) (y 3))
>            (* x y))                             ==>  6

>          (let ((x 2) (y 3))
>            (let ((x 7)
>                  (z (+ x y)))
>              (* z x)))                          ==>  35

> See also named ‘`let`’, section Iteration.

— library syntax: let* <bindings> <body>

> Syntax: <Bindings> should have the form

>     ((<variable1> <init1>) ...),

> and <body> should be a sequence of one or more expressions.

> Semantics: ‘`Let*`’ is similar to ‘`let`’, but the bindings are performed sequentially from left to right, and the region of a binding indicated by ‘`(<variable> <init>)`’ is that part of the ‘`let*`’ expression to the right of the binding. Thus the second binding is done in an environment in which the first binding is visible, and so on.

>     (let ((x 2) (y 3))
>            (let* ((x 7)
>                   (z (+ x y)))
>              (* z x)))                          ==>  70

— library syntax: letrec <bindings> <body>

> Syntax: <Bindings> should have the form

>     ((<variable1> <init1>) ...),

> and <body> should be a sequence of one or more expressions. It is an error for a <variable> to appear more than once in the list of variables being bound.

> Semantics: The <variable>s are bound to fresh locations holding undefined values, the <init>s are evaluated in the resulting environment (in some unspecified order), each <variable> is assigned to the result of the corresponding <init>, the <body> is evaluated in the resulting environment, and the value(s) of the last expression in <body> is(are) returned. Each binding of a <variable> has the entire ‘`letrec`’ expression as its region, making it possible to define mutually recursive procedures.

>          (letrec ((even?
>                    (lambda (n)
>                      (if (zero? n)
>                          #t
>                          (odd? (- n 1)))))
>                   (odd?
>                    (lambda (n)
>                      (if (zero? n)
>                          #f
>                          (even? (- n 1))))))
>            (even? 88))
>                                                 ==>  #t

> One restriction on ‘`letrec`’ is very important: it must be possible to evaluate each <init> without assigning or referring to the value of any <variable>. If this restriction is violated, then it is an error. The restriction is necessary because Scheme passes arguments by value rather than by name. In the most common uses of ‘`letrec`’, all the <init>s are lambda expressions and the restriction is satisfied automatically.