💾 Archived View for shaggypeak.com › library › r7rs › section4.2.4.gmi captured on 2023-03-20 at 19:53:47. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Section 4.2.5 - Delayed evaluation
(do ((<variable1> <init1> <step1>) ...) (<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 <expression>s.
A do expression is evaluated as follows: The <init> expressions are evaluated (in some unspecified order), the <variable>s are bound to fresh locations, the results of the <init> expressions are stored in the bindings of the <variable>s, 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 <variable>s are bound to fresh locations, the results of the <step>s are stored in the bindings of the <variable>s, and the next iteration begins.
If <test> evaluates to a true value, then the <expression>s are evaluated from left to right and the values of the last <expression> are returned. If no <expression>s 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 <init>s. 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>)
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))