274 lines
14 KiB
HTML
274 lines
14 KiB
HTML
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<!--
|
|
|
|
Generated from r6rs-lib.tex by tex2page, v 20070803
|
|
(running on MzScheme 371, unix),
|
|
(c) Dorai Sitaram,
|
|
http://www.ccs.neu.edu/~dorai/tex2page/tex2page-doc.html
|
|
|
|
-->
|
|
<head>
|
|
<title>
|
|
r6rs-lib
|
|
</title>
|
|
<link rel="stylesheet" type="text/css" href="r6rs-lib-Z-S.css" title=default>
|
|
<meta name=robots content="index,follow">
|
|
</head>
|
|
<body>
|
|
<div id=slidecontent>
|
|
<div align=right class=navigation>[Go to <span><a href="r6rs-lib.html">first</a>, <a href="r6rs-lib-Z-H-5.html">previous</a></span><span>, <a href="r6rs-lib-Z-H-7.html">next</a></span> page<span>; </span><span><a href="r6rs-lib-Z-H-1.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-lib-Z-H-21.html#node_index_start">index</a></span>]</div>
|
|
<p></p>
|
|
<a name="node_chap_5"></a>
|
|
<h1 class=chapter>
|
|
<div class=chapterheading><a href="r6rs-lib-Z-H-1.html#node_toc_node_chap_5">Chapter 5</a></div><br>
|
|
<a href="r6rs-lib-Z-H-1.html#node_toc_node_chap_5">Control structures</a></h1>
|
|
<p></p>
|
|
<p>
|
|
This chapter describes the <tt>(rnrs control (6))</tt><a name="node_idx_252"></a>library, which
|
|
provides useful control structures.</p>
|
|
<p>
|
|
</p>
|
|
<p></p>
|
|
<div align=left><tt>(<a name="node_idx_254"></a>when<i> <test> <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt></i>)</tt> syntax </div>
|
|
|
|
<div align=left><tt>(<a name="node_idx_256"></a>unless<i> <test> <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt></i>)</tt> syntax </div>
|
|
<p>
|
|
<em>Syntax: </em><Test> must be an expression.</p>
|
|
<p>
|
|
<em>Semantics: </em>A <tt>when</tt> expression is evaluated by evaluating the
|
|
<test> expression. If <test> evaluates to a true value,
|
|
the remaining <expression>s are evaluated in order, and the
|
|
results of the last <expression> are returned as the
|
|
results of the entire <tt>when</tt> expression. Otherwise, the <tt>when</tt> expression returns unspecified values. An <tt>unless</tt>
|
|
expression is evaluated by evaluating the <test> expression.
|
|
If <test> evaluates to <tt>#f</tt>, the remaining
|
|
<expression>s are evaluated in order, and the results of the
|
|
last <expression> are returned as the results of the
|
|
entire <tt>unless</tt> expression. Otherwise, the <tt>unless</tt> expression
|
|
returns unspecified values.</p>
|
|
<p>
|
|
The final <expression> is in tail context if the <tt>when</tt> or
|
|
<tt>unless</tt> form is itself in tail context.</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(when (> 3 2) ’greater) ⇒ greater<br>
|
|
(when (< 3 2) ’greater) ⇒ <em>unspecified</em><br>
|
|
(unless (> 3 2) ’less) ⇒ <em>unspecified</em><br>
|
|
(unless (< 3 2) ’less) ⇒ less<br>
|
|
<p></tt></p>
|
|
<p>
|
|
The <tt>when</tt> and <tt>unless</tt> expressions are derived forms. They
|
|
could be defined by the following macros:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>when</tt><br>
|
|
(syntax-rules ()<br>
|
|
((when test result1 result2 ...)<br>
|
|
(if test<br>
|
|
(begin result1 result2 ...)))))<br>
|
|
<br>
|
|
(define-syntax <tt>unless</tt><br>
|
|
(syntax-rules ()<br>
|
|
((unless test result1 result2 ...)<br>
|
|
(if (not test)<br>
|
|
(begin result1 result2 ...)))))<br>
|
|
<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<p></p>
|
|
<p>
|
|
</p>
|
|
|
|
<p class=noindent></p>
|
|
<div align=left><tt>(do ((<variable<sub>1</sub>> <init<sub>1</sub>> <step<sub>1</sub>>)</tt> syntax </div>
|
|
|
|
<a name="node_idx_258"></a><tt><tt>...</tt>)<br>
|
|
|
|
(<test> <expression> <tt>...</tt>)<br>
|
|
|
|
<command> <tt>...</tt>)</tt><p>
|
|
<em>Syntax: </em>The <init>s, <step>s, <test>s, and <command>s must be
|
|
expressions. The <variable>s must be pairwise distinct variables.</p>
|
|
<p>
|
|
<em>Semantics: </em>The <tt>do</tt> 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.</p>
|
|
<p>
|
|
A <tt>do</tt> 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.</p>
|
|
<p>
|
|
Each iteration begins by evaluating <test>; if the result is
|
|
<tt>#f</tt>, then the <command>s
|
|
are evaluated in order for effect, the <step>
|
|
expressions are evaluated in some unspecified order, the
|
|
<variable>s are bound to fresh locations holding the results,
|
|
and the next iteration begins.</p>
|
|
<p>
|
|
If <test> evaluates to a true value, 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 <tt>do</tt> expression returns unspecified values.</p>
|
|
<p>
|
|
The region<a name="node_idx_260"></a>of the binding of a <variable>
|
|
consists of the entire <tt>do</tt> expression except for the <init>s.</p>
|
|
<p>
|
|
A <step> may be omitted, in which case the effect is the
|
|
same as if <tt>(<variable> <init> <variable>)</tt> had
|
|
been written instead of <tt>(<variable> <init>)</tt>.</p>
|
|
<p>
|
|
If a <tt>do</tt> expression appears in a tail context, the
|
|
<expression>s are a <tail sequence> in the sense of report
|
|
section on “Tail calls and tail contexts”,
|
|
i.e., the last <expression> is also in a tail context.</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(do ((vec (make-vector 5))<br>
|
|
(i 0 (+ i 1)))<br>
|
|
((= i 5) vec)<br>
|
|
(vector-set! vec i i)) ⇒ #(0 1 2 3 4)<br>
|
|
<br>
|
|
(let ((x ’(1 3 5 7 9)))<br>
|
|
(do ((x x (cdr x))<br>
|
|
(sum 0 (+ sum (car x))))<br>
|
|
((null? x) sum))) ⇒ 25<p></tt></p>
|
|
<p>
|
|
The following definition
|
|
of <tt>do</tt> uses a trick to expand the variable clauses.</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>do</tt><br>
|
|
(syntax-rules ()<br>
|
|
((do ((var init step ...) ...)<br>
|
|
(test expr ...)<br>
|
|
command ...)<br>
|
|
(letrec<br>
|
|
((loop<br>
|
|
(lambda (var ...)<br>
|
|
(if test<br>
|
|
(begin<br>
|
|
<tt>#f</tt> ; avoid empty begin<br>
|
|
expr ...)<br>
|
|
(begin<br>
|
|
command<br>
|
|
...<br>
|
|
(loop (do "step" var step ...)<br>
|
|
...))))))<br>
|
|
(loop init ...)))<br>
|
|
((do "step" x)<br>
|
|
x)<br>
|
|
((do "step" x y)<br>
|
|
y)))<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<p>
|
|
</p>
|
|
<p></p>
|
|
<div align=left><tt>(<a name="node_idx_262"></a>case-lambda<i> <case-lambda clause> <tt>...</tt></i>)</tt> syntax </div>
|
|
<p>
|
|
<em>Syntax: </em>Each <case-lambda clause> must be of the form
|
|
</p>
|
|
|
|
<tt>(<formals> <body>)<p></tt></p>
|
|
<p>
|
|
<Formals> must be as in a <tt>lambda</tt> form
|
|
(report section on “Procedures”), and <body> is as described in
|
|
report section on “Bodies and sequences”.</p>
|
|
<p>
|
|
<em>Semantics: </em>A <tt>case-lambda</tt> expression evaluates to a procedure.
|
|
This procedure, when applied, tries to match its arguments to the
|
|
<case-lambda clause>s in order. The arguments match a clause if one of the
|
|
following conditions is fulfilled:
|
|
</p>
|
|
<ul>
|
|
<li><p><Formals> has the form <tt>(<variable> <tt>...</tt>)</tt>
|
|
and the number of arguments is the same as the number of formal
|
|
parameters in <formals>.
|
|
</p>
|
|
<li><p><Formals> has the form<br>
|
|
<tt>(<variable<sub>1</sub>> <tt>...</tt><variable<sub><em>n</em></sub>> . <variable<sub><em>n</em>+1</sub>)>
|
|
</tt><br>
|
|
and the number of arguments is at least <em>n</em>.
|
|
</p>
|
|
<li><p><Formals> has the form <tt><variable></tt>.
|
|
</p>
|
|
</ul><p>
|
|
For the first clause matched by the arguments, the variables of the
|
|
<formals> are bound to fresh locations containing the
|
|
argument values in the same arrangement as with <tt>lambda</tt>.</p>
|
|
<p>
|
|
The last expression of a <body> in a <tt>case-lambda
|
|
expression</tt> is in tail context.</p>
|
|
<p>
|
|
If the arguments match none of the clauses, an exception with condition
|
|
type <tt>&assertion</tt> is raised.</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define foo<br>
|
|
(case-lambda <br>
|
|
(() ’zero)<br>
|
|
((x) (list ’one x))<br>
|
|
((x y) (list ’two x y))<br>
|
|
((a b c d . e) (list ’four a b c d e))<br>
|
|
(rest (list ’rest rest))))<br>
|
|
<br>
|
|
(foo) ⇒ zero<br>
|
|
(foo 1) ⇒ (one 1)<br>
|
|
(foo 1 2) ⇒ (two 1 2)<br>
|
|
(foo 1 2 3) ⇒ (rest (1 2 3))<br>
|
|
(foo 1 2 3 4) ⇒ (four 1 2 3 4 ())<br>
|
|
<p></tt></p>
|
|
<p>
|
|
The <tt>case-lambda</tt> keyword
|
|
can be defined in terms of <tt>lambda</tt> by the following macros:
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>case-lambda</tt><br>
|
|
(syntax-rules ()<br>
|
|
((_ (fmls b1 b2 ...))<br>
|
|
(lambda fmls b1 b2 ...))<br>
|
|
((_ (fmls b1 b2 ...) ...)<br>
|
|
(lambda args<br>
|
|
(let ((n (length args)))<br>
|
|
(case-lambda-help args n<br>
|
|
(fmls b1 b2 ...) ...))))))<br>
|
|
<br>
|
|
(define-syntax case-lambda-help<br>
|
|
(syntax-rules ()<br>
|
|
((_ args n)<br>
|
|
(assertion-violation <tt>#f</tt><br>
|
|
"unexpected number of arguments"))<br>
|
|
((_ args n ((x ...) b1 b2 ...) more ...)<br>
|
|
(if (= n (length ’(x ...)))<br>
|
|
(apply (lambda (x ...) b1 b2 ...) args)<br>
|
|
(case-lambda-help args n more ...)))<br>
|
|
((_ args n ((x1 x2 ... . r) b1 b2 ...) more ...)<br>
|
|
(if (>= n (length ’(x1 x2 ...)))<br>
|
|
(apply (lambda (x1 x2 ... . r) b1 b2 ...)<br>
|
|
args)<br>
|
|
(case-lambda-help args n more ...)))<br>
|
|
((_ args n (r b1 b2 ...) more ...)<br>
|
|
(apply (lambda r b1 b2 ...) args))))<br>
|
|
<p></tt>
|
|
</p>
|
|
<p></p>
|
|
<p>
|
|
</p>
|
|
<p></p>
|
|
<div class=smallskip></div>
|
|
<p style="margin-top: 0pt; margin-bottom: 0pt">
|
|
<div align=right class=navigation>[Go to <span><a href="r6rs-lib.html">first</a>, <a href="r6rs-lib-Z-H-5.html">previous</a></span><span>, <a href="r6rs-lib-Z-H-7.html">next</a></span> page<span>; </span><span><a href="r6rs-lib-Z-H-1.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-lib-Z-H-21.html#node_index_start">index</a></span>]</div>
|
|
</p>
|
|
<p></p>
|
|
</div>
|
|
</body>
|
|
</html>
|