1024 lines
59 KiB
HTML
1024 lines
59 KiB
HTML
|
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||
|
<html>
|
||
|
<!-- Generated from TeX source by tex2page, v 4o4,
|
||
|
(c) Dorai Sitaram, http://www.cs.rice.edu/~dorai/tex2page -->
|
||
|
<head>
|
||
|
<title>
|
||
|
Revised^5 Report on the Algorithmic Language Scheme
|
||
|
</title>
|
||
|
<link rel="stylesheet" type="text/css" href="r5rs-Z-C.css" title=default>
|
||
|
<meta name=robots content="noindex,follow">
|
||
|
</head>
|
||
|
<body>
|
||
|
|
||
|
<p><div class=navigation>[Go to <span><a href="r5rs.html">first</a>, <a href="r5rs-Z-H-6.html">previous</a></span><span>, <a href="r5rs-Z-H-8.html">next</a></span> page<span>; </span><span><a href="r5rs-Z-H-2.html#%_toc_start">contents</a></span><span><span>; </span><a href="r5rs-Z-H-15.html#%_index_start">index</a></span>]</div><p>
|
||
|
|
||
|
<a name="%_chap_4"></a>
|
||
|
<h1 class=chapter>
|
||
|
<div class=chapterheading><a href="r5rs-Z-H-2.html#%_toc_%_chap_4">Chapter 4</a></div><p>
|
||
|
<a href="r5rs-Z-H-2.html#%_toc_%_chap_4">Expressions</a></h1><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
|
||
|
<p>
|
||
|
|
||
|
|
||
|
Expression types are categorized as <em>primitive</em> or <em>derived</em>.
|
||
|
Primitive expression types include variables and procedure calls.
|
||
|
Derived expression types are not semantically primitive, but can instead
|
||
|
be defined as macros.
|
||
|
With the exception of <tt>quasiquote</tt>, whose macro definition is complex,
|
||
|
the derived expressions are classified as library features.
|
||
|
Suitable definitions are given in section <a href="r5rs-Z-H-10.html#%_sec_7.3">7.3</a>.<p>
|
||
|
|
||
|
<a name="%_sec_4.1"></a>
|
||
|
<h2><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1">4.1 Primitive expression types</a></h2><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
<a name="%_sec_4.1.1"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.1">4.1.1 Variable references</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt><variable></tt> </div>
|
||
|
<p>
|
||
|
|
||
|
An expression consisting of a variable<a name="%_idx_82"></a>
|
||
|
(section <a href="r5rs-Z-H-6.html#%_sec_3.1">3.1</a>) is a variable reference. The value of
|
||
|
the variable reference is the value stored in the location to which the
|
||
|
variable is bound. It is an error to reference an
|
||
|
unbound<a name="%_idx_84"></a> variable.<p>
|
||
|
|
||
|
<tt><p>(define x 28)<br>
|
||
|
x ===> 28<p></tt>
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.1.2"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.2">4.1.2 Literal expressions</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_86"></a>quote<i> <datum></i>)</tt> </div>
|
||
|
|
||
|
<div align=left><u>syntax:</u> <tt><tt>'</tt><datum></tt> </div>
|
||
|
|
||
|
<div align=left><u>syntax:</u> <tt><constant></tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<tt>(quote <datum>)</tt> evaluates to <datum>.<a name="%_idx_88"></a>
|
||
|
<Datum>
|
||
|
may be any external representation of a Scheme object (see
|
||
|
section <a href="r5rs-Z-H-6.html#%_sec_3.3">3.3</a>). This notation is used to include literal
|
||
|
constants in Scheme code.<p>
|
||
|
|
||
|
<tt><p>(quote a) ===> a<br>
|
||
|
(quote <tt>#</tt>(a b c)) ===> #(a b c)<br>
|
||
|
(quote (+ 1 2)) ===> (+ 1 2)<p></tt><p>
|
||
|
|
||
|
<tt>(quote <datum>)</tt> may be abbreviated as
|
||
|
<tt>'</tt><datum>. The two notations are equivalent in all
|
||
|
respects.<p>
|
||
|
|
||
|
<tt><p>'a ===> a<br>
|
||
|
'#(a b c) ===> #(a b c)<br>
|
||
|
'() ===> ()<br>
|
||
|
'(+ 1 2) ===> (+ 1 2)<br>
|
||
|
'(quote a) ===> (quote a)<br>
|
||
|
''a ===> (quote a)<p></tt><p>
|
||
|
|
||
|
Numerical constants, string constants, character constants, and boolean
|
||
|
constants evaluate ``to themselves''; they need not be quoted.<p>
|
||
|
|
||
|
<tt><p>'"abc" ===> "abc"<br>
|
||
|
"abc" ===> "abc"<br>
|
||
|
'145932 ===> 145932<br>
|
||
|
145932 ===> 145932<br>
|
||
|
'<tt>#t</tt> ===> <tt>#t</tt><br>
|
||
|
<tt>#t</tt> ===> <tt>#t</tt><p></tt><p>
|
||
|
|
||
|
As noted in section <a href="r5rs-Z-H-6.html#%_sec_3.4">3.4</a>, it is an error to alter a constant
|
||
|
(i.e. the value of a literal expression) using a mutation procedure like
|
||
|
<tt>set-car!</tt> or <tt>string-set!</tt>.<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.1.3"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.3">4.1.3 Procedure calls</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<operator> <operand<sub>1</sub>> <tt>...</tt>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
A procedure call is written by simply enclosing in parentheses
|
||
|
expressions for the procedure to be called and the arguments to be
|
||
|
passed to it. The operator and operand expressions are evaluated (in an
|
||
|
unspecified order) and the resulting procedure is passed the resulting
|
||
|
arguments.<a name="%_idx_90"></a><a name="%_idx_92"></a>
|
||
|
<tt><p>(+ 3 4) ===> 7<br>
|
||
|
((if <tt>#f</tt> + *) 3 4) ===> 12<p></tt><p>
|
||
|
|
||
|
A number of procedures are available as the values of variables in the
|
||
|
initial environment; for example, the addition and multiplication
|
||
|
procedures in the above examples are the values of the variables <tt>+</tt>
|
||
|
and <tt>*</tt>. New procedures are created by evaluating <tt>lambda</tt> expressions
|
||
|
(see section <a href="#%_sec_4.1.4">4.1.4</a>).
|
||
|
|
||
|
|
||
|
Procedure calls may return any number of values (see <tt>values</tt> in
|
||
|
section <a href="r5rs-Z-H-9.html#%_sec_6.4">6.4</a>). With the exception of <tt>values</tt>
|
||
|
the procedures available in the initial environment return one
|
||
|
value or, for procedures such as <tt>apply</tt>, pass on the values returned
|
||
|
by a call to one of their arguments.<p>
|
||
|
|
||
|
Procedure calls are also called <em>combinations</em>.
|
||
|
<a name="%_idx_94"></a><p>
|
||
|
|
||
|
<blockquote><em>Note: </em> In contrast to other dialects of Lisp, the order of
|
||
|
evaluation is unspecified, and the operator expression and the operand
|
||
|
expressions are always evaluated with the same evaluation rules.
|
||
|
</blockquote><p>
|
||
|
|
||
|
<blockquote><em>Note: </em>
|
||
|
Although the order of evaluation is otherwise unspecified, the effect of
|
||
|
any concurrent evaluation of the operator and operand expressions is
|
||
|
constrained to be consistent with some sequential order of evaluation.
|
||
|
The order of evaluation may be chosen differently for each procedure call.
|
||
|
</blockquote><p>
|
||
|
|
||
|
<blockquote><em>Note: </em> In many dialects of Lisp, the empty combination, <tt>()</tt>, is a legitimate expression. In Scheme, combinations must have at
|
||
|
least one subexpression, so <tt>()</tt> is not a syntactically valid
|
||
|
expression.
|
||
|
</blockquote><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.1.4"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.4">4.1.4 Procedures</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_96"></a>lambda<i> <formals> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Formals> should be a formal arguments list as described below,
|
||
|
and <body> should be a sequence of one or more expressions.<p>
|
||
|
|
||
|
<em>Semantics: </em>A <tt>lambda</tt> expression evaluates to a procedure. The environment in
|
||
|
effect when the <tt>lambda</tt> expression was evaluated is remembered as part of the
|
||
|
procedure. When the procedure is later called with some actual
|
||
|
arguments, the environment in which the <tt>lambda</tt> expression was evaluated will
|
||
|
be extended by binding the variables in the formal argument list to
|
||
|
fresh locations, the corresponding actual argument values will be stored
|
||
|
in those locations, and the expressions in the body of the <tt>lambda</tt> expression
|
||
|
will be evaluated sequentially in the extended environment.
|
||
|
The result(s) of the last expression in the body will be returned as
|
||
|
the result(s) of the procedure call.<p>
|
||
|
|
||
|
<tt><p>(lambda (x) (+ x x)) ===> <em>a procedure</em><br>
|
||
|
((lambda (x) (+ x x)) 4) ===> 8<br>
|
||
|
<br>
|
||
|
(define reverse-subtract<br>
|
||
|
(lambda (x y) (- y x)))<br>
|
||
|
(reverse-subtract 7 10) ===> 3<br>
|
||
|
<br>
|
||
|
(define add4<br>
|
||
|
(let ((x 4))<br>
|
||
|
(lambda (y) (+ x y))))<br>
|
||
|
(add4 6) ===> 10<p></tt><p>
|
||
|
|
||
|
<Formals> should have one of the following forms:<p>
|
||
|
|
||
|
<p><ul>
|
||
|
<li><tt>(<variable<sub>1</sub>> <tt>...</tt>)</tt>:
|
||
|
The procedure takes a fixed number of arguments; when the procedure is
|
||
|
called, the arguments will be stored in the bindings of the
|
||
|
corresponding variables.<p>
|
||
|
|
||
|
<li><variable>:
|
||
|
The procedure takes any number of arguments; when the procedure is
|
||
|
called, the sequence of actual arguments is converted into a newly
|
||
|
allocated list, and the list is stored in the binding of the
|
||
|
<variable>.<p>
|
||
|
|
||
|
<li><tt>(<variable<sub>1</sub>> <tt>...</tt> <variable<sub><em>n</em></sub>> <strong>.</strong>
|
||
|
<variable<sub><em>n</em>+1</sub>>)</tt>:
|
||
|
If a space-delimited period precedes the last variable, then
|
||
|
the procedure takes <em>n</em> or more arguments, where <em>n</em> is the
|
||
|
number of formal arguments before the period (there must
|
||
|
be at least one).
|
||
|
The value stored in the binding of the last variable will be a
|
||
|
newly allocated
|
||
|
list of the actual arguments left over after all the other actual
|
||
|
arguments have been matched up against the other formal arguments.
|
||
|
</ul><p><p>
|
||
|
|
||
|
It is an error for a <variable> to appear more than once in
|
||
|
<formals>.<p>
|
||
|
|
||
|
<tt><p>((lambda x x) 3 4 5 6) ===> (3 4 5 6)<br>
|
||
|
((lambda (x y . z) z)<br>
|
||
|
3 4 5 6) ===> (5 6)<p></tt><p>
|
||
|
|
||
|
Each procedure created as the result of evaluating a <tt>lambda</tt> expression is
|
||
|
(conceptually) tagged
|
||
|
with a storage location, in order to make <tt>eqv?</tt> and
|
||
|
<tt>eq?</tt> work on procedures (see section <a href="r5rs-Z-H-9.html#%_sec_6.1">6.1</a>).<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.1.5"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.5">4.1.5 Conditionals</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_98"></a>if<i> <test> <consequent> <alternate></i>)</tt> </div>
|
||
|
|
||
|
<div align=left><u>syntax:</u> <tt>(if<i> <test> <consequent></i>)</tt> </div>
|
||
|
|
||
|
<em>Syntax: </em><Test>, <consequent>, and <alternate> may be arbitrary
|
||
|
expressions.<p>
|
||
|
|
||
|
<em>Semantics: </em>An <tt>if</tt> expression is evaluated as follows: first,
|
||
|
<test> is evaluated. If it yields a true value<a name="%_idx_100"></a> (see
|
||
|
section <a href="r5rs-Z-H-9.html#%_sec_6.3.1">6.3.1</a>), then <consequent> is evaluated and
|
||
|
its value(s) is(are) returned. Otherwise <alternate> is evaluated and its
|
||
|
value(s) is(are) returned. If <test> yields a false value and no
|
||
|
<alternate> is specified, then the result of the expression is
|
||
|
unspecified.<p>
|
||
|
|
||
|
<tt><p>(if (> 3 2) 'yes 'no) ===> yes<br>
|
||
|
(if (> 2 3) 'yes 'no) ===> no<br>
|
||
|
(if (> 3 2)<br>
|
||
|
(- 3 2)<br>
|
||
|
(+ 3 2)) ===> 1<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.1.6"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.1.6">4.1.6 Assignments</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_102"></a>set!<i> <variable> <expression></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<Expression> is evaluated, and the resulting value is stored in
|
||
|
the location to which <variable> is bound. <Variable> must
|
||
|
be bound either in some region<a name="%_idx_104"></a> enclosing the <tt>set!</tt> expression
|
||
|
or at top level. The result of the <tt>set!</tt> expression is
|
||
|
unspecified.<p>
|
||
|
|
||
|
<tt><p>(define x 2)<br>
|
||
|
(+ x 1) ===> 3<br>
|
||
|
(set! x 4) ===> <i>unspecified</i><br>
|
||
|
(+ x 1) ===> 5<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2"></a>
|
||
|
<h2><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2">4.2 Derived expression types</a></h2><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
The constructs in this section are hygienic, as discussed in
|
||
|
section <a href="#%_sec_4.3">4.3</a>.
|
||
|
For reference purposes, section <a href="r5rs-Z-H-10.html#%_sec_7.3">7.3</a> gives macro definitions
|
||
|
that will convert most of the constructs described in this section
|
||
|
into the primitive constructs described in the previous section.<p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
<a name="%_sec_4.2.1"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.1">4.2.1 Conditionals</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_106"></a>cond<i> <clause<sub>1</sub>> <clause<sub>2</sub>> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em>Each <clause> should be of the form
|
||
|
<tt><p>(<test> <expression<sub>1</sub>> <tt>...</tt>)<p></tt>
|
||
|
where <test> is any expression. Alternatively, a <clause> may be
|
||
|
of the form
|
||
|
<tt><p>(<test> => <expression>)<p></tt>
|
||
|
The last <clause> may be
|
||
|
an ``else clause,'' which has the form
|
||
|
<tt><p>(else <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt>).<p></tt>
|
||
|
<a name="%_idx_108"></a>
|
||
|
<a name="%_idx_110"></a><p>
|
||
|
|
||
|
<em>Semantics: </em>A <tt>cond</tt> expression is evaluated by evaluating the <test>
|
||
|
expressions of successive <clause>s in order until one of them
|
||
|
evaluates to a true value<a name="%_idx_112"></a> (see
|
||
|
section <a href="r5rs-Z-H-9.html#%_sec_6.3.1">6.3.1</a>). When a <test> evaluates to a true
|
||
|
value, then the remaining <expression>s in its <clause> are
|
||
|
evaluated in order, and the result(s) of the last <expression> in the
|
||
|
<clause> is(are) returned as the result(s) of the entire <tt>cond</tt>
|
||
|
expression. If the selected <clause> contains only the
|
||
|
<test> and no <expression>s, then the value of the
|
||
|
<test> is returned as the result. If the selected <clause> uses the
|
||
|
<tt>=></tt> alternate form, then the <expression> is evaluated.
|
||
|
Its value must be a procedure that accepts one argument; this procedure is then
|
||
|
called on the value of the <test> and the value(s) returned by this
|
||
|
procedure is(are) returned by the <tt>cond</tt> expression.
|
||
|
If all <test>s evaluate
|
||
|
to false values, and there is no else clause, then the result of
|
||
|
the conditional expression is unspecified; if there is an else
|
||
|
clause, then its <expression>s are evaluated, and the value(s) of
|
||
|
the last one is(are) returned.<p>
|
||
|
|
||
|
<tt><p>(cond ((> 3 2) 'greater)<br>
|
||
|
((< 3 2) 'less)) ===> greater<br>
|
||
|
(cond ((> 3 3) 'greater)<br>
|
||
|
((< 3 3) 'less)<br>
|
||
|
(else 'equal)) ===> equal<br>
|
||
|
(cond ((assv 'b '((a 1) (b 2))) => cadr)<br>
|
||
|
(else <tt>#f</tt>)) ===> 2<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_114"></a>case<i> <key> <clause<sub>1</sub>> <clause<sub>2</sub>> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Key> may be any expression. Each <clause> should have
|
||
|
the form
|
||
|
<tt><p>((<datum<sub>1</sub>> <tt>...</tt>) <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt>),<p></tt>
|
||
|
where each <datum> is an external representation of some object.
|
||
|
All the <datum>s must be distinct.
|
||
|
The last <clause> may be an ``else clause,'' which has the form
|
||
|
<tt><p>(else <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt>).<p></tt>
|
||
|
<a name="%_idx_116"></a><p>
|
||
|
|
||
|
<em>Semantics: </em>A <tt>case</tt> expression is evaluated as follows. <Key> is
|
||
|
evaluated and its result is compared against each <datum>. If the
|
||
|
result of evaluating <key> is equivalent (in the sense of
|
||
|
<tt>eqv?</tt>; see section <a href="r5rs-Z-H-9.html#%_sec_6.1">6.1</a>) to a <datum>, then the
|
||
|
expressions in the corresponding <clause> are evaluated from left
|
||
|
to right and the result(s) of the last expression in the <clause> is(are)
|
||
|
returned as the result(s) of the <tt>case</tt> expression. If the result of
|
||
|
evaluating <key> is different from every <datum>, then if
|
||
|
there is an else clause its expressions are evaluated and the
|
||
|
result(s) of the last is(are) the result(s) of the <tt>case</tt> expression;
|
||
|
otherwise the result of the <tt>case</tt> expression is unspecified.<p>
|
||
|
|
||
|
<tt><p>(case (* 2 3)<br>
|
||
|
((2 3 5 7) 'prime)<br>
|
||
|
((1 4 6 8 9) 'composite)) ===> composite<br>
|
||
|
(case (car '(c d))<br>
|
||
|
((a) 'a)<br>
|
||
|
((b) 'b)) ===> <i>unspecified</i><br>
|
||
|
(case (car '(c d))<br>
|
||
|
((a e i o u) 'vowel)<br>
|
||
|
((w y) 'semivowel)<br>
|
||
|
(else 'consonant)) ===> consonant<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_118"></a>and<i> <test<sub>1</sub>> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
The <test> expressions are evaluated from left to right, and the
|
||
|
value of the first expression that evaluates to a false value (see
|
||
|
section <a href="r5rs-Z-H-9.html#%_sec_6.3.1">6.3.1</a>) is returned. Any remaining expressions
|
||
|
are not evaluated. If all the expressions evaluate to true values, the
|
||
|
value of the last expression is returned. If there are no expressions
|
||
|
then <tt>#t</tt> is returned.<p>
|
||
|
|
||
|
<tt><p>(and (= 2 2) (> 2 1)) ===> <tt>#t</tt><br>
|
||
|
(and (= 2 2) (< 2 1)) ===> <tt>#f</tt><br>
|
||
|
(and 1 2 'c '(f g)) ===> (f g)<br>
|
||
|
(and) ===> <tt>#t</tt><p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_120"></a>or<i> <test<sub>1</sub>> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
The <test> expressions are evaluated from left to right, and the value of the
|
||
|
first expression that evaluates to a true value (see
|
||
|
section <a href="r5rs-Z-H-9.html#%_sec_6.3.1">6.3.1</a>) is returned. Any remaining expressions
|
||
|
are not evaluated. If all expressions evaluate to false values, the
|
||
|
value of the last expression is returned. If there are no
|
||
|
expressions then <tt>#f</tt> is returned.<p>
|
||
|
|
||
|
<tt><p>(or (= 2 2) (> 2 1)) ===> <tt>#t</tt><br>
|
||
|
(or (= 2 2) (< 2 1)) ===> <tt>#t</tt><br>
|
||
|
(or <tt>#f</tt> <tt>#f</tt> <tt>#f</tt>) ===> <tt>#f</tt><br>
|
||
|
(or (memq 'b '(a b c)) <br>
|
||
|
(/ 3 0)) ===> (b c)<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2.2"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.2">4.2.2 Binding constructs</a></h3><p>
|
||
|
|
||
|
The three binding constructs <tt>let</tt>, <tt>let*</tt>, and <tt>letrec</tt>
|
||
|
give Scheme a block structure, like Algol 60. The syntax of the three
|
||
|
constructs is identical, but they differ in the regions<a name="%_idx_122"></a> they establish
|
||
|
for their variable bindings. In a <tt>let</tt> expression, the initial
|
||
|
values are computed before any of the variables become bound; in a
|
||
|
<tt>let*</tt> expression, the bindings and evaluations are performed
|
||
|
sequentially; while in a <tt>letrec</tt> expression, all the bindings are in
|
||
|
effect while their initial values are being computed, thus allowing
|
||
|
mutually recursive definitions.<p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_124"></a>let<i> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Bindings> should have the form
|
||
|
<tt><p>((<variable<sub>1</sub>> <init<sub>1</sub>>) <tt>...</tt>),<p></tt>
|
||
|
where each <init> is an expression, and <body> should be a
|
||
|
sequence of one or more expressions. It is
|
||
|
an error for a <variable> to appear more than once in the list of variables
|
||
|
being bound.<p>
|
||
|
|
||
|
<em>Semantics: </em>The <init>s are evaluated in the current environment (in some
|
||
|
unspecified order), the <variable>s are bound to fresh locations
|
||
|
holding the results, the <body> is evaluated in the extended
|
||
|
environment, and the value(s) of the last expression of <body>
|
||
|
is(are) returned. Each binding of a <variable> has <body> as its
|
||
|
region.<a name="%_idx_126"></a><p>
|
||
|
|
||
|
<tt><p>(let ((x 2) (y 3))<br>
|
||
|
(* x y)) ===> 6<br>
|
||
|
<br>
|
||
|
(let ((x 2) (y 3))<br>
|
||
|
(let ((x 7)<br>
|
||
|
(z (+ x y)))<br>
|
||
|
(* z x))) ===> 35<p></tt><p>
|
||
|
|
||
|
See also named <tt>let</tt>, section <a href="#%_sec_4.2.4">4.2.4</a>.<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_128"></a>let*<i> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Bindings> should have the form
|
||
|
<tt><p>((<variable<sub>1</sub>> <init<sub>1</sub>>) <tt>...</tt>),<p></tt>
|
||
|
and <body> should be a sequence of
|
||
|
one or more expressions.<p>
|
||
|
|
||
|
<em>Semantics: </em><tt>Let*</tt> is similar to <tt>let</tt>, but the bindings are performed
|
||
|
sequentially from left to right, and the region<a name="%_idx_130"></a> of a binding indicated
|
||
|
by <tt>(<variable> <init>)</tt> is that part of the <tt>let*</tt>
|
||
|
expression to the right of the binding. Thus the second binding is done
|
||
|
in an environment in which the first binding is visible, and so on.<p>
|
||
|
|
||
|
<tt><p>(let ((x 2) (y 3))<br>
|
||
|
(let* ((x 7)<br>
|
||
|
(z (+ x y)))<br>
|
||
|
(* z x))) ===> 70<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_132"></a>letrec<i> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Bindings> should have the form
|
||
|
<tt><p>((<variable<sub>1</sub>> <init<sub>1</sub>>) <tt>...</tt>),<p></tt>
|
||
|
and <body> should be a sequence of
|
||
|
one or more expressions. It is an error for a <variable> to appear more
|
||
|
than once in the list of variables being bound.<p>
|
||
|
|
||
|
<em>Semantics: </em>The <variable>s are bound to fresh locations holding undefined
|
||
|
values, the <init>s are evaluated in the resulting environment (in
|
||
|
some unspecified order), each <variable> is assigned to the result
|
||
|
of the corresponding <init>, the <body> is evaluated in the
|
||
|
resulting environment, and the value(s) of the last expression in
|
||
|
<body> is(are) returned. Each binding of a <variable> has the
|
||
|
entire <tt>letrec</tt> expression as its region<a name="%_idx_134"></a>, making it possible to
|
||
|
define mutually recursive procedures.<p>
|
||
|
|
||
|
<tt><p>(letrec ((even?<br>
|
||
|
(lambda (n)<br>
|
||
|
(if (zero? n)<br>
|
||
|
<tt>#t</tt><br>
|
||
|
(odd? (- n 1)))))<br>
|
||
|
(odd?<br>
|
||
|
(lambda (n)<br>
|
||
|
(if (zero? n)<br>
|
||
|
<tt>#f</tt><br>
|
||
|
(even? (- n 1))))))<br>
|
||
|
(even? 88)) <br>
|
||
|
===> <tt>#t</tt><p></tt><p>
|
||
|
|
||
|
One restriction on <tt>letrec</tt> is very important: it must be possible
|
||
|
to evaluate each <init> without assigning or referring to the value of any
|
||
|
<variable>. If this restriction is violated, then it is an error. The
|
||
|
restriction is necessary because Scheme passes arguments by value rather than by
|
||
|
name. In the most common uses of <tt>letrec</tt>, all the <init>s are
|
||
|
<tt>lambda</tt> expressions and the restriction is satisfied automatically.<p>
|
||
|
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2.3"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.3">4.2.3 Sequencing</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_136"></a>begin<i> <expression<sub>1</sub>> <expression<sub>2</sub>> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
The <expression>s are evaluated sequentially from left to right,
|
||
|
and the value(s) of the last <expression> is(are) returned. This
|
||
|
expression type is used to sequence side effects such as input and
|
||
|
output.<p>
|
||
|
|
||
|
<tt><p>(define x 0)<br>
|
||
|
<br>
|
||
|
(begin (set! x 5)<br>
|
||
|
(+ x 1)) ===> 6<br>
|
||
|
<br>
|
||
|
(begin (display "4 plus 1 equals ")<br>
|
||
|
(display (+ 4 1))) ===> <i>unspecified</i><br>
|
||
|
<em> and prints</em> 4 plus 1 equals 5<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2.4"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.4">4.2.4 Iteration</a></h3><p>
|
||
|
|
||
|
|
||
|
<div align=left><u>library syntax:</u> <tt>(do ((<variable<sub>1</sub>> <init<sub>1</sub>> <step<sub>1</sub>>)</tt> </div>
|
||
|
|
||
|
<a name="%_idx_138"></a><tt> <tt>...</tt>)<br>
|
||
|
(<test> <expression> <tt>...</tt>)<br>
|
||
|
<command> <tt>...</tt>)</tt><p>
|
||
|
|
||
|
<tt>Do</tt> 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.<p>
|
||
|
|
||
|
<tt>Do</tt> expressions are 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>
|
||
|
|
||
|
Each iteration begins by evaluating <test>; if the result is
|
||
|
false (see section <a href="r5rs-Z-H-9.html#%_sec_6.3.1">6.3.1</a>), 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.<p>
|
||
|
|
||
|
If <test> evaluates to a true value, then the
|
||
|
<expression>s are evaluated from left to right and the value(s) of
|
||
|
the last <expression> is(are) returned. If no <expression>s
|
||
|
are present, then the value of the <tt>do</tt> expression is unspecified.<p>
|
||
|
|
||
|
The region<a name="%_idx_140"></a> of the binding of a <variable>
|
||
|
consists of the entire <tt>do</tt> expression except for the <init>s.
|
||
|
It is an error for a <variable> to appear more than once in the
|
||
|
list of <tt>do</tt> variables.<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>
|
||
|
|
||
|
<tt><p>(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>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(let<i> <variable> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
|
||
|
``Named <tt>let</tt>'' is a variant on the syntax of <tt>let</tt> which provides
|
||
|
a more general looping construct than <tt>do</tt> and may also be used to express
|
||
|
recursions.
|
||
|
It has the same syntax and semantics as ordinary <tt>let</tt>
|
||
|
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> may be repeated by
|
||
|
invoking the procedure named by <variable>.<p>
|
||
|
|
||
|
<tt><p>(let loop ((numbers '(3 -2 1 6 -5))<br>
|
||
|
(nonneg '())<br>
|
||
|
(neg '()))<br>
|
||
|
(cond ((null? numbers) (list nonneg neg))<br>
|
||
|
((>= (car numbers) 0)<br>
|
||
|
(loop (cdr numbers)<br>
|
||
|
(cons (car numbers) nonneg)<br>
|
||
|
neg))<br>
|
||
|
((< (car numbers) 0)<br>
|
||
|
(loop (cdr numbers)<br>
|
||
|
nonneg<br>
|
||
|
(cons (car numbers) neg))))) <br> ===> ((6 1 3) (-5 -2))<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2.5"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.5">4.2.5 Delayed evaluation</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>library syntax:</u> <tt>(<a name="%_idx_142"></a>delay<i> <expression></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
The <tt>delay</tt> construct is used together with the procedure <tt>force</tt> to
|
||
|
implement <a name="%_idx_144"></a><em>lazy evaluation</em> or <a name="%_idx_146"></a><em>call by need</em>.
|
||
|
<tt>(delay <expression>)</tt> returns an object called a
|
||
|
<a name="%_idx_148"></a><em>promise</em> which at some point in the future may be asked (by
|
||
|
the <tt>force</tt> procedure) to evaluate
|
||
|
<expression>, and deliver the resulting value.
|
||
|
The effect of <expression> returning multiple values
|
||
|
is unspecified.<p>
|
||
|
|
||
|
See the description of <tt>force</tt> (section <a href="r5rs-Z-H-9.html#%_sec_6.4">6.4</a>) for a
|
||
|
more complete description of <tt>delay</tt>.<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.2.6"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.2.6">4.2.6 Quasiquotation</a></h3><p>
|
||
|
|
||
|
<p><p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_150"></a>quasiquote<i> <qq template></i>)</tt> </div>
|
||
|
<div align=left><u>syntax:</u> <tt><tt>`</tt><qq template></tt> </div>
|
||
|
<p>
|
||
|
|
||
|
``Backquote'' or ``quasiquote''<a name="%_idx_152"></a> expressions are useful
|
||
|
for constructing a list or vector structure when most but not all of the
|
||
|
desired structure is known in advance. If no
|
||
|
commas<a name="%_idx_154"></a> appear within the <qq template>, the result of
|
||
|
evaluating
|
||
|
<tt>`</tt><qq template> is equivalent to the result of evaluating
|
||
|
<tt>'</tt><qq template>. If a comma<a name="%_idx_156"></a> appears within the
|
||
|
<qq template>, however, the expression following the comma is
|
||
|
evaluated (``unquoted'') and its result is inserted into the structure
|
||
|
instead of the comma and the expression. If a comma appears followed
|
||
|
immediately by an at-sign (<tt>@</tt>),<a name="%_idx_158"></a> then the following
|
||
|
expression must evaluate to a list; the opening and closing parentheses
|
||
|
of the list are then ``stripped away'' and the elements of the list are
|
||
|
inserted in place of the comma at-sign expression sequence. A comma
|
||
|
at-sign should only appear within a list or vector <qq template>.<p>
|
||
|
|
||
|
|
||
|
<tt><p>`(list ,(+ 1 2) 4) ===> (list 3 4)<br>
|
||
|
(let ((name 'a)) `(list ,name ',name)) <br> ===> (list a (quote a))<br>
|
||
|
`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b) <br> ===> (a 3 4 5 6 b)<br>
|
||
|
`((<tt> foo</tt> ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons))) <br> ===> ((foo 7) . cons)<br>
|
||
|
`#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8) <br> ===> #(10 5 2 4 3 8)<p></tt><p>
|
||
|
|
||
|
Quasiquote forms may be nested. Substitutions are made only for
|
||
|
unquoted components appearing at the same nesting level
|
||
|
as the outermost backquote. The nesting level increases by one inside
|
||
|
each successive quasiquotation, and decreases by one inside each
|
||
|
unquotation.<p>
|
||
|
|
||
|
<tt><p>`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f) <br> ===> (a `(b ,(+ 1 2) ,(foo 4 d) e) f)<br>
|
||
|
(let ((name1 'x)<br>
|
||
|
(name2 'y))<br>
|
||
|
`(a `(b ,,name1 ,',name2 d) e)) <br> ===> (a `(b ,x ,'y d) e)<p></tt><p>
|
||
|
|
||
|
The two notations
|
||
|
<tt>`</tt><qq template> and <tt>(quasiquote <qq template>)</tt>
|
||
|
are identical in all respects.
|
||
|
<tt>,<expression></tt> is identical to <tt>(unquote <expression>)</tt>,
|
||
|
and
|
||
|
<tt>,@<expression></tt> is identical to <tt>(unquote-splicing <expression>)</tt>.
|
||
|
The external syntax generated by <tt>write</tt> for two-element lists whose
|
||
|
car is one of these symbols may vary between implementations.
|
||
|
<a name="%_idx_160"></a><p>
|
||
|
|
||
|
<tt><p>(quasiquote (list (unquote (+ 1 2)) 4)) <br> ===> (list 3 4)<br>
|
||
|
'(quasiquote (list (unquote (+ 1 2)) 4)) <br> ===> `(list ,(+ 1 2) 4)<br>
|
||
|
<em>i.e.,</em> (quasiquote (list (unquote (+ 1 2)) 4))<p></tt><p>
|
||
|
|
||
|
Unpredictable behavior can result if any of the symbols
|
||
|
<tt>quasiquote</tt>, <tt>unquote</tt>, or <tt>unquote-splicing</tt> appear in
|
||
|
positions within a <qq template> otherwise than as described above.<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.3"></a>
|
||
|
<h2><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.3">4.3 Macros</a></h2><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
Scheme programs can define and use new derived expression types,
|
||
|
called <em>macros</em>.<a name="%_idx_162"></a>
|
||
|
Program-defined expression types have the syntax
|
||
|
<tt><p>(<keyword> <datum> ...)<p></tt>where <keyword> is an identifier that uniquely determines the
|
||
|
expression type. This identifier is called the <em>syntactic
|
||
|
keyword</em><a name="%_idx_164"></a>, or simply <em>keyword</em><a name="%_idx_166"></a>, of the macro<a name="%_idx_168"></a>. The
|
||
|
number of the <datum>s, and their syntax, depends on the
|
||
|
expression type.<p>
|
||
|
|
||
|
Each instance of a macro is called a <em>use</em><a name="%_idx_170"></a>
|
||
|
of the macro.
|
||
|
The set of rules that specifies
|
||
|
how a use of a macro is transcribed into a more primitive expression
|
||
|
is called the <em>transformer</em><a name="%_idx_172"></a>
|
||
|
of the macro.<p>
|
||
|
|
||
|
The macro definition facility consists of two parts:<p>
|
||
|
|
||
|
<p><ul>
|
||
|
<li>A set of expressions used to establish that certain identifiers
|
||
|
are macro keywords, associate them with macro transformers, and control
|
||
|
the scope within which a macro is defined, and<p>
|
||
|
|
||
|
<li>a pattern language for specifying macro transformers.
|
||
|
</ul><p><p>
|
||
|
|
||
|
The syntactic keyword of a macro may shadow variable bindings, and local
|
||
|
variable bindings may shadow keyword bindings. <a name="%_idx_174"></a> All macros
|
||
|
defined using the pattern language are ``hygienic'' and ``referentially
|
||
|
transparent'' and thus preserve Scheme's lexical scoping [<a href="r5rs-Z-H-14.html#%_sec_7.3">14</a>, <a href="r5rs-Z-H-14.html#%_sec_7.3">15</a>, <a href="r5rs-Z-H-14.html#%_sec_7.3">2</a>, <a href="r5rs-Z-H-14.html#%_sec_7.3">7</a>, <a href="r5rs-Z-H-14.html#%_sec_7.3">9</a>]:
|
||
|
<a name="%_idx_176"></a>
|
||
|
<a name="%_idx_178"></a><p>
|
||
|
|
||
|
<p><ul><p>
|
||
|
|
||
|
<li>If a macro transformer inserts a binding for an identifier
|
||
|
(variable or keyword), the identifier will in effect be renamed
|
||
|
throughout its scope to avoid conflicts with other identifiers.
|
||
|
Note that a <tt>define</tt> at top level may or may not introduce a binding;
|
||
|
see section <a href="r5rs-Z-H-8.html#%_sec_5.2">5.2</a>.<p>
|
||
|
|
||
|
<li>If a macro transformer inserts a free reference to an
|
||
|
identifier, the reference refers to the binding that was visible
|
||
|
where the transformer was specified, regardless of any local
|
||
|
bindings that may surround the use of the macro.<p>
|
||
|
|
||
|
</ul><p><p>
|
||
|
|
||
|
|
||
|
|
||
|
<a name="%_sec_4.3.1"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.3.1">4.3.1 Binding constructs for syntactic keywords</a></h3><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
<tt>Let-syntax</tt> and <tt>letrec-syntax</tt> are
|
||
|
analogous to <tt>let</tt> and <tt>letrec</tt>, but they bind
|
||
|
syntactic keywords to macro transformers instead of binding variables
|
||
|
to locations that contain values. Syntactic keywords may also be
|
||
|
bound at top level; see section <a href="r5rs-Z-H-8.html#%_sec_5.3">5.3</a>.<p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_180"></a>let-syntax<i> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Bindings> should have the form
|
||
|
<tt><p>((<keyword> <transformer spec>) <tt>...</tt>)<p></tt>
|
||
|
Each <keyword> is an identifier,
|
||
|
each <transformer spec> is an instance of <tt>syntax-rules</tt>, and
|
||
|
<body> should be a sequence of one or more expressions. It is an error
|
||
|
for a <keyword> to appear more than once in the list of keywords
|
||
|
being bound.<p>
|
||
|
|
||
|
<em>Semantics: </em>The <body> is expanded in the syntactic environment
|
||
|
obtained by extending the syntactic environment of the
|
||
|
<tt>let-syntax</tt> expression with macros whose keywords are
|
||
|
the <keyword>s, bound to the specified transformers.
|
||
|
Each binding of a <keyword> has <body> as its region.<p>
|
||
|
|
||
|
<tt><p>(let-syntax ((when (syntax-rules ()<br>
|
||
|
((when test stmt1 stmt2 ...)<br>
|
||
|
(if test<br>
|
||
|
(begin stmt1<br>
|
||
|
stmt2 ...))))))<br>
|
||
|
(let ((if <tt>#t</tt>))<br>
|
||
|
(when if (set! if 'now))<br>
|
||
|
if)) ===> now<br>
|
||
|
<br>
|
||
|
(let ((x 'outer))<br>
|
||
|
(let-syntax ((m (syntax-rules () ((m) x))))<br>
|
||
|
(let ((x 'inner))<br>
|
||
|
(m)))) ===> outer<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p><div align=left><u>syntax:</u> <tt>(<a name="%_idx_182"></a>letrec-syntax<i> <bindings> <body></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em>Same as for <tt>let-syntax</tt>.<p>
|
||
|
|
||
|
<em>Semantics: </em>The <body> is expanded in the syntactic environment obtained by
|
||
|
extending the syntactic environment of the <tt>letrec-syntax</tt>
|
||
|
expression with macros whose keywords are the
|
||
|
<keyword>s, bound to the specified transformers.
|
||
|
Each binding of a <keyword> has the <bindings>
|
||
|
as well as the <body> within its region,
|
||
|
so the transformers can
|
||
|
transcribe expressions into uses of the macros
|
||
|
introduced by the <tt>letrec-syntax</tt> expression.<p>
|
||
|
|
||
|
<tt><p>(letrec-syntax<br>
|
||
|
((my-or (syntax-rules ()<br>
|
||
|
((my-or) <tt>#f</tt>)<br>
|
||
|
((my-or e) e)<br>
|
||
|
((my-or e1 e2 ...)<br>
|
||
|
(let ((temp e1))<br>
|
||
|
(if temp<br>
|
||
|
temp<br>
|
||
|
(my-or e2 ...)))))))<br>
|
||
|
(let ((x <tt>#f</tt>)<br>
|
||
|
(y 7)<br>
|
||
|
(temp 8)<br>
|
||
|
(let odd?)<br>
|
||
|
(if even?))<br>
|
||
|
(my-or x<br>
|
||
|
(let temp)<br>
|
||
|
(if y)<br>
|
||
|
y))) ===> 7<p></tt><p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<a name="%_sec_4.3.2"></a>
|
||
|
<h3><a href="r5rs-Z-H-2.html#%_toc_%_sec_4.3.2">4.3.2 Pattern language</a></h3><p>
|
||
|
|
||
|
<p>
|
||
|
|
||
|
A <transformer spec> has the following form:<p>
|
||
|
|
||
|
<p><div align=left><u>:</u> <tt>(<a name="%_idx_184"></a>syntax-rules<i> <literals> <syntax rule> <tt>...</tt></i>)</tt> </div>
|
||
|
<p>
|
||
|
|
||
|
<em>Syntax: </em><Literals> is a list of identifiers and each <syntax rule>
|
||
|
should be of the form
|
||
|
<tt><p>(<pattern> <template>)<p></tt>
|
||
|
The <pattern> in a <syntax rule> is a list <pattern>
|
||
|
that begins with the keyword for the macro.<p>
|
||
|
|
||
|
A <pattern> is either an identifier, a constant, or one of the
|
||
|
following
|
||
|
<tt><p>(<pattern> <tt>...</tt>)<br>
|
||
|
(<pattern> <pattern> <tt>...</tt> . <pattern>)<br>
|
||
|
(<pattern> <tt>...</tt> <pattern> <ellipsis>)<br>
|
||
|
#(<pattern> <tt>...</tt>)<br>
|
||
|
#(<pattern> <tt>...</tt> <pattern> <ellipsis>)<p></tt>
|
||
|
and a template is either an identifier, a constant, or one of the following
|
||
|
<tt><p>(<element> <tt>...</tt>)<br>
|
||
|
(<element> <element> <tt>...</tt> . <template>)<br>
|
||
|
#(<element> <tt>...</tt>)<p></tt>
|
||
|
where an <element> is a <template> optionally
|
||
|
followed by an <ellipsis> and
|
||
|
an <ellipsis> is the identifier ``<tt>...</tt>'' (which cannot be used as
|
||
|
an identifier in either a template or a pattern).<a name="%_idx_186"></a><p>
|
||
|
|
||
|
<em>Semantics: </em>An instance of <tt>syntax-rules</tt> produces a new macro
|
||
|
transformer by specifying a sequence of hygienic rewrite rules. A use
|
||
|
of a macro whose keyword is associated with a transformer specified by
|
||
|
<tt>syntax-rules</tt> is matched against the patterns contained in the
|
||
|
<syntax rule>s, beginning with the leftmost <syntax rule>.
|
||
|
When a match is found, the macro use is transcribed hygienically
|
||
|
according to the template.<p>
|
||
|
|
||
|
An identifier that appears in the pattern of a <syntax rule> is
|
||
|
a <em>pattern variable</em>, unless it is the keyword that begins the pattern,
|
||
|
is listed in <literals>, or is the identifier ``<tt>...</tt>''.
|
||
|
Pattern variables match arbitrary input elements and
|
||
|
are used to refer to elements of the input in the template. It is an
|
||
|
error for the same pattern variable to appear more than once in a
|
||
|
<pattern>.<p>
|
||
|
|
||
|
The keyword at the beginning of the pattern in a
|
||
|
<syntax rule> is not involved in the matching and
|
||
|
is not considered a pattern variable or literal identifier.<p>
|
||
|
|
||
|
<blockquote><em>Rationale: </em>
|
||
|
The scope of the keyword is determined by the expression or syntax
|
||
|
definition that binds it to the associated macro transformer.
|
||
|
If the keyword were a pattern variable or literal
|
||
|
identifier, then
|
||
|
the template that follows the pattern would be within its scope
|
||
|
regardless of whether the keyword were bound by <tt>let-syntax</tt>
|
||
|
or by <tt>letrec-syntax</tt>.
|
||
|
</blockquote><p>
|
||
|
|
||
|
Identifiers that appear in <literals> are interpreted as literal
|
||
|
identifiers to be matched against corresponding subforms of the input.
|
||
|
A subform
|
||
|
in the input matches a literal identifier if and only if it is an
|
||
|
identifier
|
||
|
and either both its occurrence in the macro expression and its
|
||
|
occurrence in the macro definition have the same lexical binding, or
|
||
|
the two identifiers are equal and both have no lexical binding.<p>
|
||
|
|
||
|
|
||
|
A subpattern followed by <tt>...</tt> can match zero or more elements of the
|
||
|
input. It is an error for <tt>...</tt> to appear in <literals>.
|
||
|
Within a pattern the identifier <tt>...</tt> must follow the last element of
|
||
|
a nonempty sequence of subpatterns.<p>
|
||
|
|
||
|
More formally, an input form <em>F</em> matches a pattern <em>P</em> if and only if:<p>
|
||
|
|
||
|
<p><ul>
|
||
|
<li><em>P</em> is a non-literal identifier; or<p>
|
||
|
|
||
|
<li><em>P</em> is a literal identifier and <em>F</em> is an identifier with the same
|
||
|
binding; or<p>
|
||
|
|
||
|
<li><em>P</em> is a list <tt>(<em>P</em><sub>1</sub> <tt>...</tt> <em>P</em><sub><em>n</em></sub>)</tt> and <em>F</em> is a
|
||
|
list of <em>n</em>
|
||
|
forms that match <em>P</em><sub>1</sub> through <em>P</em><sub><em>n</em></sub>, respectively; or<p>
|
||
|
|
||
|
<li><em>P</em> is an improper list
|
||
|
<tt>(<em>P</em><sub>1</sub> <em>P</em><sub>2</sub> <tt>...</tt> <em>P</em><sub><em>n</em></sub> . <em>P</em><sub><em>n</em>+1</sub>)</tt>
|
||
|
and <em>F</em> is a list or
|
||
|
improper list of <em>n</em> or more forms that match <em>P</em><sub>1</sub> through <em>P</em><sub><em>n</em></sub>,
|
||
|
respectively, and whose <em>n</em>th ``cdr'' matches <em>P</em><sub><em>n</em>+1</sub>; or<p>
|
||
|
|
||
|
<li><em>P</em> is of the form
|
||
|
<tt>(<em>P</em><sub>1</sub> <tt>...</tt> <em>P</em><sub><em>n</em></sub> <em>P</em><sub><em>n</em>+1</sub> <ellipsis>)</tt>
|
||
|
where <ellipsis> is the identifier <tt>...</tt>
|
||
|
and <em>F</em> is
|
||
|
a proper list of at least <em>n</em> forms, the first <em>n</em> of which match
|
||
|
<em>P</em><sub>1</sub> through <em>P</em><sub><em>n</em></sub>, respectively, and each remaining element of <em>F</em>
|
||
|
matches <em>P</em><sub><em>n</em>+1</sub>; or<p>
|
||
|
|
||
|
<li><em>P</em> is a vector of the form <tt>#(<em>P</em><sub>1</sub> <tt>...</tt> <em>P</em><sub><em>n</em></sub>)</tt>
|
||
|
and <em>F</em> is a vector
|
||
|
of <em>n</em> forms that match <em>P</em><sub>1</sub> through <em>P</em><sub><em>n</em></sub>; or<p>
|
||
|
|
||
|
<li><em>P</em> is of the form
|
||
|
<tt>#(<em>P</em><sub>1</sub> <tt>...</tt> <em>P</em><sub><em>n</em></sub> <em>P</em><sub><em>n</em>+1</sub> <ellipsis>)</tt>
|
||
|
where <ellipsis> is the identifier <tt>...</tt>
|
||
|
and <em>F</em> is a vector of <em>n</em>
|
||
|
or more forms the first <em>n</em> of which match
|
||
|
<em>P</em><sub>1</sub> through <em>P</em><sub><em>n</em></sub>, respectively, and each remaining element of <em>F</em>
|
||
|
matches <em>P</em><sub><em>n</em>+1</sub>; or<p>
|
||
|
|
||
|
<li><em>P</em> is a datum and <em>F</em> is equal to <em>P</em> in the sense of
|
||
|
the <tt>equal?</tt> procedure.
|
||
|
</ul><p><p>
|
||
|
|
||
|
It is an error to use a macro keyword, within the scope of its
|
||
|
binding, in an expression that does not match any of the patterns.<p>
|
||
|
|
||
|
When a macro use is transcribed according to the template of the
|
||
|
matching <syntax rule>, pattern variables that occur in the
|
||
|
template are replaced by the subforms they match in the input.
|
||
|
Pattern variables that occur in subpatterns followed by one or more
|
||
|
instances of the identifier
|
||
|
<tt>...</tt> are allowed only in subtemplates that are
|
||
|
followed by as many instances of <tt>...</tt>.
|
||
|
They are replaced in the
|
||
|
output by all of the subforms they match in the input, distributed as
|
||
|
indicated. It is an error if the output cannot be built up as
|
||
|
specified.<p>
|
||
|
|
||
|
|
||
|
Identifiers that appear in the template but are not pattern variables
|
||
|
or the identifier
|
||
|
<tt>...</tt> are inserted into the output as literal identifiers. If a
|
||
|
literal identifier is inserted as a free identifier then it refers to the
|
||
|
binding of that identifier within whose scope the instance of
|
||
|
<tt>syntax-rules</tt> appears.
|
||
|
If a literal identifier is inserted as a bound identifier then it is
|
||
|
in effect renamed to prevent inadvertent captures of free identifiers.<p>
|
||
|
|
||
|
As an example, if <tt>let</tt> and <tt>cond</tt> are defined as in
|
||
|
section <a href="r5rs-Z-H-10.html#%_sec_7.3">7.3</a> then they are hygienic (as required) and
|
||
|
the following is not an error.<p>
|
||
|
|
||
|
<tt><p>(let ((=> <tt>#f</tt>))<br>
|
||
|
(cond (<tt>#t</tt> => 'ok))) ===> ok<p></tt><p>
|
||
|
|
||
|
The macro transformer for <tt>cond</tt> recognizes <tt>=></tt>
|
||
|
as a local variable, and hence an expression, and not as the
|
||
|
top-level identifier <tt>=></tt>, which the macro transformer treats
|
||
|
as a syntactic keyword. Thus the example expands into<p>
|
||
|
|
||
|
<tt><p>(let ((=> <tt>#f</tt>))<br>
|
||
|
(if <tt>#t</tt> (begin => 'ok)))<p></tt><p>
|
||
|
|
||
|
instead of<p>
|
||
|
|
||
|
<tt><p>(let ((=> <tt>#f</tt>))<br>
|
||
|
(let ((temp <tt>#t</tt>))<br>
|
||
|
(if temp ('ok temp))))<p></tt><p>
|
||
|
|
||
|
which would result in an invalid procedure call.<p>
|
||
|
|
||
|
<p><p>
|
||
|
|
||
|
<p>
|
||
|
<p><div class=navigation>[Go to <span><a href="r5rs.html">first</a>, <a href="r5rs-Z-H-6.html">previous</a></span><span>, <a href="r5rs-Z-H-8.html">next</a></span> page<span>; </span><span><a href="r5rs-Z-H-2.html#%_toc_start">contents</a></span><span><span>; </span><a href="r5rs-Z-H-15.html#%_index_start">index</a></span>]</div><p>
|
||
|
|
||
|
</body>
|
||
|
</html>
|