Node:Binding constructs, Next:Sequencing, Previous:Conditional, Up:Derived expression types
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.
let <bindings> <body> | library syntax |
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* <bindings> <body> | library syntax |
Syntax:
<Bindings> should have the form
((<variable1> <init1>) ...), and <body> should be a sequence of one or more expressions. Semantics:
(let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x))) ==> 70 |
letrec <bindings> <body> | library syntax |
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 ((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 |