The following example loops 10 times while accumulating each value of i to j and returns it.
(do ((i 0 (+ i 1)) (j 0 (+ i j))) ((= i 10) j) (print j)) ⇒ 45 ; also prints intermediate values of j
If step is omitted, the previous value of variable
is carried over. When there’s no expr, the non-false
value returned by test becomes the value of the
do syntax uses many parentheses, some prefer using
square brackets as well as parentheses to visually distinguish
the groupings. A common way is to group each variable binding,
and the test clause, by square brackets.
(do ([i 0 (+ i 1)] [j 0 (+ i j)]) [(= i 10) j] (print j))
Note: Unlike Common Lisp (and “for loops” in many languages), variable is freshly bound for each iteration. The following example loops 5 times and creates a list of closures, each of which closes the variable i. When you call each closures, you can see that each of them closes different i at the time of the iteration they were created.
(define closures (do ([i 0 (+ i 1)] [c '() (cons (^ i) c)]) [(= i 5) (reverse c)] )) ((car closures)) ⇒ 0 ((cadr closures)) ⇒ 1
This variation of
let is called “named let”. It creates
the following procedure and binds it to name, then calls
it with init ….
(lambda (var …) body …)
This syntax itself isn’t necessarily related to iteration. However, the whole point of named let is that the above lambda expression is within the scope of name—that is, you can call name recursively within body. Hence this is used very often to write a loop by recursion (thus, often the procedure is named loop, as in the following example.)
(let loop ([x 0] [y '()]) (if (= x 10) y (loop (+ x 1) (cons x y)))) ⇒ (9 8 7 6 5 4 3 2 1 0)
Of course you don’t need to loop with a named let; you can call name
in non-tail position, pass name to other higher-order procedure, etc.
Named let exists since it captures a very common pattern of local recursive
Some Schemers even prefer named let to
do, for the better
The following rewrite rule precisely explains the named let semantics.
The tricky use of
letrec in the expansion is to make
proc visible from body … but not from init ….
(let proc ((var init) …) body …) ≡ ((letrec ((proc (lambda (var …) body …))) proc) init …)
Convenience loop syntaxes, imported from Common Lisp. They are not very Scheme-y, in a sense that these rely on some side-effects in body …. Nevertheless these capture some common pattern in day-to-day scripting.
You can use
dotimes to repeat body … for a number
of times given by num-expr,
dolist to repeat body …
while traversing a list given by list-expr. While body …
variable is bound to the current iteration count (in
or the current element in the list (in
(dotimes (n 5) (write n)) ⇒ writes "12345" (dolist (v '(a b c d e)) (write v)) ⇒ writes "abcde"
If you don’t need to refer to variable, you can omit it.
For example, the following example prints
year! 10 times:
(dotimes (10) (print "yeah!"))
If the third element (result) is given in
dolist, it is evaluated after all repetition is done, and its result
becomes the result of
dolist. While result
is evaluated, variable is bound to the number of repetitions
It is supported because Common Lisp has it.
Note that a fresh variable is bound for each iteration, as opposed to Common Lisp where variable is mutated. So if you create a closure closing variable, it won’t be overwritten by the subsequent iteration.
If you need more than simple iteration, you can use
let, or Eager comprehensions, which provides
rich way to iterate.
=>var body …
=>var body …
Var is an identifier and guard is a procedure that takes one argument.
In the first form, expr is evaluated, and if it yields a true value, body … are evaluated. It is repeated while expr yields true value.
In the second form, var is bound to a result of expr in the scope of body ….
In the third form, the value expr yields are passed to guard, and the execution of body … is repeated while guard returns a true value. var is bound to the result of expr.
The return value of
while form itself isn’t specified.
(let ((a '(0 1 2 3 4))) (while (pair? a) (write (pop! a)))) ⇒ prints "01234" (let ((a '(0 1 2 3 #f 5 6))) (while (pop! a) integer? => var (write var))) ⇒ prints "0123"
=>var body …
while, but the condition is reversed. That is,
the first form repeats evaluation of expr and body …
until expr yields true. In the second form,
the result of expr is passed to guard, and the
execution is repeated until it returns true. Var is bound
to the result of expr.
(The second form without guard isn’t useful in
var would always be bound to
The return value of
until form itself isn’t specified.
(let ((a '(0 1 2 3 4))) (until (null? a) (write (pop! a)))) ⇒ prints "01234" (until (read-char) eof-object? => ch (write-char ch)) ⇒ reads from stdin and writes char until EOF is read