Iteration

(do (({variable1} {init1} {step1}) ...) syntax
({test} {expression} ...)
{command} ...)
Syntax All of init, step, test, and command are expressions.

Semantics: A do expression is 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 after evaluating the expressions.

A do expression is 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 (see section 6.3), 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 values of the last expression are returned. If no expressions are present, then the value of the do expression is unspecified.

The region of the binding of a variable consists of the entire do expression except for the inits. It is an error for a variable to appear more than once in the list of do variables.

A step can be omitted, in which case the effect is the same as if (variable init variable) had been written instead of (variable init).

(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

(let {variable} {bindings} {body} ) syntax
Semantics: "Named let" is a variant on the syntax of let which provides a more general looping construct than do and can also be used to express recursion. It has the same syntax and semantics as ordinary let except that variable is bound within body to a procedure whose formal arguments are the bound variables and whose body is body. Thus the execution of body can be repeated by invoking the procedure named by variable.

(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))

husk-scheme online documentation rev 3.2 (2021.03.04)