Control Structures
----------------------------------------------------------------
_Control Structures_
----------------------------------------------------------------
(require (planet "control.scm" ("soegaard" "control.plt")))
This package provide the control structures
- while
- until
- dotimes
- tagged-begin
> (while <test> <body>) macro
Syntax: <test> should be an expression and <body> a
sequence of one or more expressions.
Semantics: WHILE is an iteration construct. Each iteration begins by
evaluating the <test> expression. If it evaluates to a
true value, the <body> expressions are evaluated
sequentially from left to right, then the next iteration
begins. If the <test> expression evaluates to false then
iteration stops and an unspecified value is returned
as the result of the while-expression.
Example: (let ([n 3] [sum 0])
(while (> n 0)
(set! sum (+ sum n))
(set! n (- n 1))
sum)
=> 6
> (until <test> <body>) MACRO
Syntax: <test> should be an expression and <body> a
sequence of one or more expressions.
Semantics: UNTIL is an iteration construct. Each iteration
begins by evaluating the <body> expressions
sequentially from left to right. The <test>
expression is then evaluated. If the result is
a true value, then the next iteration begins.
Otherwise the iteration stops and unspecified
value is returned as the result of the
until-expression.
Example: (let ([n 3] [sum 0])
(until (= n 1)
(set! sum (+ sum n))
(set! n (- n 1)))
sum)
=> 5
> (dotimes (<variable> <expression> [<finally>]) <body>) MACRO
Syntax: <variable> should be an identifier, <expression>
and <finally> (if present) should be expressions and
<body> a sequence of one or more expressions.
Semantics: DOTIMES is an iteration contructs. Evalutations begins
by evaluating <expression>. If the result is not an
integer an error is signaled. If the result is zero or
negative, the <body> expressions are not evaluated.
Otherwise the <body> expressions are evaluated for each
integer from 0 up to but not including the result of
<expression>.
During each evaluation of the <body> expressions,
<variable> is bound to each integer.
When the iteration stops <finally> is evaluated if
present and the result returned, otherwise #void is
returned. During evaluation of <finally> the <variable>
is bound to the number of times the body were evaluated.
Examples: (let ((xs '()))
(dotimes (x 5)
(set! xs (cons x xs)))
xs)
=> (4 3 2 1 0)
(let ((xs '()))
(dotimes (x 5 (list xs x))
(set! xs (cons x xs))))
=> ((4 3 2 1 0) 5)
> (tagged-begin (<tag> | <expression>)* ) MACRO
Syntax: <tag> should be a symbol, and all <tag>s should be different.
Motivation: The macro tagged-begin is inspired by the Common Lisp
construct tagbody.
Semantics: The tagged-begin expression evaluates the expressions
in a lexical environment, where GO and RETURN are
are bound to functions of one argument, which will
transfer control when called.
As main rule the expressions will be evaluated sequentially
from left to right. When there are no more expressions to
be evaluated #void is returned.
If an expression evaluates (go <tag>) then control is transfered
to the expression following the tag. The tags have lexical scope.
The dynamic extent of tag is indefinite. An (go tag) is allowed to
tranfer control to an outer tagged-begin. The call (go tag) has the
proper tail recursive property, even in situation where the call
syntactically is not in tail position.
If (return <expression>) is evaluted, the value of <expression> is
returned as the value of the entire tagged-begin form.
Examples: (let ([i 0])
(tagged-begin
loop (set! i (+ i 1))
(if (< i 41) (go loop)))
i)
=> 41
(let ((odd-numbers '())
(a 0))
(tagged-begin
start (set! a 0)
on-odd (set! a (+ a 1))
(set! odd-numbers (cons a odd-numbers))
(cond
((>= a 9) (go end))
((even? a) (go on-even))
(else (go on-odd)))
on-even (set! a (+ a 1))
(go on-odd)
end)
odd-numbers))
=> (list 9 7 5 3 1)
References: "Applications of Continuations" of Daniel P. Friedman.
Keywords: _control_ _cl_ _tagbody_ _knuth_ _go_ _return_ _loop_ _iteration_