The three binding constructs let
, let*
, and letrec
are available
in STKLOS. These constructs 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> | R5RS |
let <variable> <bindings> <body> | R5RS |
In a let , <bindings> should have the form
((<variable1> <init1>) ...) where each The (let ((x 2) (y 3)) (* x y)) => 6 (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x))) => 35 The second form of (let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) => ((6 1 3) (-5 -2)) |
let* <bindings> <body> | R5RS |
In a let* , <bindings> should have the same form as in a let (however, a
<variable> can appear more than once in the list of variables being bound).
(<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 |
letrec <bindings> <body> | R5RS |
<bindings> should have the form as in let .
The (letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88)) => #t |
fluid-let <bindings> <body> | STKLOS Syntax |
The <bindings> are evaluated in the current environment, in some
unspecified order, the current values of the variables present in
<bindings> are saved, and the new evaluated values are assigned to the
<bindings> variables. Once this is done, the expressions of <body>
are evaluated sequentially in the current environment; the value of the
last expression is the result of fluid-let . Upon exit, the stored
variables values are restored. An error is signalled if any of the
<bindings> variable is unbound.
(let* ((a 'out) (f (lambda () a))) (list (f) (fluid-let ((a 'in)) (f)) (f))) => (out in out) When the body of a (let ((cont #f) (l '()) (a 'out)) (set! l (cons a l)) (fluid-let ((a 'in)) (set! cont (call-with-current-continuation (lambda (k) k))) (set! l (cons a l))) (set! l (cons a l)) (if cont (cont #f) l)) => (out in out in out) |