The iteration expressions are: “named
They are also binding expressions, but are more commonly referred to as
iteration expressions. Because Scheme is properly tail-recursive, you
don't need to use these special forms to express iteration; you can
simply use appropriately written “recursive” procedure calls.
lethas the same syntax and semantics as ordinary
letexcept that name is bound within the expressions to a procedure whose formal arguments are the variables and whose body is the expressions. Thus the execution of the expressions may be repeated by invoking the procedure named by name.
Note: the following expressions are equivalent:(let name ((variable init) ...) expression expression ...) ((letrec ((name (named-lambda (name variable ...) expression expression ...))) name) init ...)
Here is an example:(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)) (else (loop (cdr numbers) nonneg (cons (car numbers) neg))))) => ((6 1 3) (-5 -2))
dois an iteration construct. It specifies a set of variables to be bound, how they are to be initialized at the start, and how they are to be updated on each iteration. When a termination condition is met, the loop exits with a specified result value.
doexpressions are evaluated as follows: The init expressions are evaluated (in some unspecified order), the variables are bound to fresh locations, the results of the init expressions are stored in the bindings of the variables, and then the iteration phase begins.
Each iteration begins by evaluating test; if the result is false, then the command expressions are evaluated in order for effect, the step expressions are evaluated in some unspecified order, the variables are bound to fresh locations, the results of the steps are stored in the bindings of the variables, and the next iteration begins.
If test evaluates to a true value, then the expressions are evaluated from left to right and the value of the last expression is returned as the value of the
doexpression. If no expressions are present, then the value of the
doexpression is unspecified in standard Scheme; in MIT/GNU Scheme, the value of test is returned.
A step may be omitted, in which case the effect is the same as if
(variable init variable
)had been written instead of
).(do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) => #(0 1 2 3 4) (let ((x '(1 3 5 7 9))) (do ((x x (cdr x)) (sum 0 (+ sum (car x)))) ((null? x) sum))) => 25