Local variables are bound with standard Scheme's let, let*, and letrec. An additional form, letrec*, is similar to a letrec expression, but while the evaluation order of binding expressions is undefined for letrec in standard Scheme, the letrec* form gurantees sequential evaualtion of the binding expressions.
Multiple values are bound to multiple local variables at once with
let-values, let*-values, letrec-values, and
letrec*-values. The syntax for let-values is:
(let-values (((variable ) expr) ) body-expr )
As in define-values, the number of values returned by each
expr must match the number of variables declared in
the corresponding clause. Each expr remains outside of the scope
of all variables bound by the let-values expression.
The syntax for let*-values, letrec-values, and letrec*-values is the same as for let-values, and the binding semantics for each form corresponds to the single-value binding form:
When a letrec, letrec*, letrec-values, or letrec*-values expression is evaluated, each variable binding is initially assigned the special undefined value (see section 4.1); the undefined value is replaced once the corresponding expression is evaluated.
Examples:
(define x 0)
(let ([x 5] [y x]) y) ; => 0
(let* ([x 5] [y x]) y) ; => 5
(letrec* ([x 5] [y x]) y) ; => 5
(letrec* ([x y] [y 5]) x) ; => undefined
(let-values ([(x) 5] [(y) x]) y) ; => 0
(let-values ([(x y) (values 5 x)]) y) ; => 0
(let*-values ([(x) 5] [(y) x]) y) ; => 5
(let*-values ([(x y) (values 5 x)]) y) ; => 0
(letrec*-values ([(x) 5] [(y) x]) y) ; => 5
(letrec*-values ([(x y) (values 5 x)]) y) ; => undefined
(letrec*-values ([(odd even)
(values
(lambda (n) (if (zero? n) #f (even (sub1 n))))
(lambda (n) (if (zero? n) #t (odd (sub1 n)))))])
(odd 17)) ; => #t