318 lines
18 KiB
HTML
318 lines
18 KiB
HTML
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<!--
|
|
|
|
Generated from r6rs.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>
|
|
Revised^6 Report on the Algorithmic Language Scheme
|
|
</title>
|
|
<link rel="stylesheet" type="text/css" href="r6rs-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.html">first</a>, <a href="r6rs-Z-H-15.html">previous</a></span><span>, <a href="r6rs-Z-H-17.html">next</a></span> page<span>; </span><span><a href="r6rs-Z-H-2.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-Z-H-21.html#node_index_start">index</a></span>]</div>
|
|
<p></p>
|
|
<a name="node_chap_B"></a>
|
|
<h1 class=chapter>
|
|
<div class=chapterheading><a href="r6rs-Z-H-2.html#node_toc_node_chap_B">Appendix B</a></div><br>
|
|
<a href="r6rs-Z-H-2.html#node_toc_node_chap_B">Sample definitions for derived forms</a></h1>
|
|
<p></p>
|
|
<p>
|
|
This appendix contains sample definitions for some of the keywords
|
|
described in this report in terms of simpler forms:</p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_37"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_37"><tt>cond</tt></a></h4>
|
|
<p>The <tt>cond</tt> keyword (section <a href="r6rs-Z-H-14.html#node_sec_11.4.5">11.4.5</a>)
|
|
could be defined in terms of <tt>if</tt>, <tt>let</tt> and <tt>begin</tt> using <tt>syntax-rules</tt> as follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>cond</tt><br>
|
|
(syntax-rules (else =>)<br>
|
|
((cond (else result1 result2 ...))<br>
|
|
(begin result1 result2 ...))<br>
|
|
((cond (test => result))<br>
|
|
(let ((temp test))<br>
|
|
(if temp (result temp))))<br>
|
|
((cond (test => result) clause1 clause2 ...)<br>
|
|
(let ((temp test))<br>
|
|
(if temp<br>
|
|
(result temp)<br>
|
|
(cond clause1 clause2 ...))))<br>
|
|
((cond (test)) test)<br>
|
|
((cond (test) clause1 clause2 ...)<br>
|
|
(let ((temp test))<br>
|
|
(if temp<br>
|
|
temp<br>
|
|
(cond clause1 clause2 ...))))<br>
|
|
((cond (test result1 result2 ...))<br>
|
|
(if test (begin result1 result2 ...)))<br>
|
|
((cond (test result1 result2 ...)<br>
|
|
clause1 clause2 ...)<br>
|
|
(if test<br>
|
|
(begin result1 result2 ...)<br>
|
|
(cond clause1 clause2 ...)))))<p></tt>
|
|
</p>
|
|
<a name="node_sec_Temp_38"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_38"><tt>case</tt></a></h4>
|
|
<p>The <tt>case</tt> keyword (section <a href="r6rs-Z-H-14.html#node_sec_11.4.5">11.4.5</a>) could be defined in terms of <tt>let</tt>, <tt>cond</tt>, and
|
|
<tt>memv</tt> (see library chapter on “List utilities”) using <tt>syntax-rules</tt> as follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>case</tt><br>
|
|
(syntax-rules (else)<br>
|
|
((case expr0<br>
|
|
((key ...) res1 res2 ...)<br>
|
|
...<br>
|
|
(else else-res1 else-res2 ...))<br>
|
|
(let ((tmp expr0))<br>
|
|
(cond<br>
|
|
((memv tmp ’(key ...)) res1 res2 ...)<br>
|
|
...<br>
|
|
(else else-res1 else-res2 ...))))<br>
|
|
((case expr0<br>
|
|
((keya ...) res1a res2a ...)<br>
|
|
((keyb ...) res1b res2b ...)<br>
|
|
...)<br>
|
|
(let ((tmp expr0))<br>
|
|
(cond<br>
|
|
((memv tmp ’(keya ...)) res1a res2a ...)<br>
|
|
((memv tmp ’(keyb ...)) res1b res2b ...)<br>
|
|
...)))))<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_39"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_39"><tt>let*</tt></a></h4>
|
|
<p>The <tt>let*</tt> keyword (section <a href="r6rs-Z-H-14.html#node_sec_11.4.6">11.4.6</a>)
|
|
could be defined in terms of <tt>let</tt>
|
|
using <tt>syntax-rules</tt> as follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>let*</tt><br>
|
|
(syntax-rules ()<br>
|
|
((let* () body1 body2 ...)<br>
|
|
(let () body1 body2 ...))<br>
|
|
((let* ((name1 expr1) (name2 expr2) ...)<br>
|
|
body1 body2 ...)<br>
|
|
(let ((name1 expr1))<br>
|
|
(let* ((name2 expr2) ...)<br>
|
|
body1 body2 ...)))))<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_40"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_40"><tt>letrec</tt></a></h4>
|
|
<p>The <tt>letrec</tt> keyword (section <a href="r6rs-Z-H-14.html#node_sec_11.4.6">11.4.6</a>)
|
|
could be defined approximately in terms of <tt>let</tt>
|
|
and <tt>set!</tt> using <tt>syntax-rules</tt>, using a helper
|
|
to generate the temporary variables
|
|
needed to hold the values before the assignments are made,
|
|
as follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>letrec</tt><br>
|
|
(syntax-rules ()<br>
|
|
((letrec () body1 body2 ...)<br>
|
|
(let () body1 body2 ...))<br>
|
|
((letrec ((var init) ...) body1 body2 ...)<br>
|
|
(letrec-helper<br>
|
|
(var ...)<br>
|
|
()<br>
|
|
((var init) ...)<br>
|
|
body1 body2 ...))))<br>
|
|
<br>
|
|
(define-syntax letrec-helper<br>
|
|
(syntax-rules ()<br>
|
|
((letrec-helper<br>
|
|
()<br>
|
|
(temp ...)<br>
|
|
((var init) ...)<br>
|
|
body1 body2 ...)<br>
|
|
(let ((var <undefined>) ...)<br>
|
|
(let ((temp init) ...)<br>
|
|
(set! var temp)<br>
|
|
...)<br>
|
|
(let () body1 body2 ...)))<br>
|
|
((letrec-helper<br>
|
|
(x y ...)<br>
|
|
(temp ...)<br>
|
|
((var init) ...)<br>
|
|
body1 body2 ...)<br>
|
|
(letrec-helper<br>
|
|
(y ...)<br>
|
|
(newtemp temp ...)<br>
|
|
((var init) ...)<br>
|
|
body1 body2 ...))))<p></tt></p>
|
|
<p>
|
|
The syntax <tt><undefined></tt> represents an expression that
|
|
returns something that, when stored in a location, causes an exception
|
|
with condition type <tt>&assertion</tt> to
|
|
be raised if an attempt to read from or write to the location occurs before the
|
|
assignments generated by the <tt>letrec</tt> transformation take place.
|
|
(No such expression is defined in Scheme.)</p>
|
|
<p>
|
|
A simpler definition using <tt>syntax-case</tt> and <tt>generate-temporaries</tt> is given in library
|
|
chapter on “<tt>syntax-case</tt>”.</p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_41"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_41"><tt>letrec*</tt></a></h4>
|
|
<p>The <tt>letrec*</tt> keyword could be defined approximately in terms of
|
|
<tt>let</tt> and <tt>set!</tt> using <tt>syntax-rules</tt> as follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>letrec*</tt><br>
|
|
(syntax-rules ()<br>
|
|
((letrec* ((var1 init1) ...) body1 body2 ...)<br>
|
|
(let ((var1 <undefined>) ...)<br>
|
|
(set! var1 init1)<br>
|
|
...<br>
|
|
(let () body1 body2 ...)))))<p></tt></p>
|
|
<p>
|
|
The syntax <tt><undefined></tt> is as in the definition of <tt>letrec</tt> above.</p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_42"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_42"><tt>let-values</tt></a></h4>
|
|
<p>The following definition of <tt>let-values</tt> (section <a href="r6rs-Z-H-14.html#node_sec_11.4.6">11.4.6</a>)
|
|
using <tt>syntax-rules</tt>
|
|
employs a pair of helpers to
|
|
create temporary names for the formals.</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax let-values<br>
|
|
(syntax-rules ()<br>
|
|
((let-values (binding ...) body1 body2 ...)<br>
|
|
(let-values-helper1<br>
|
|
()<br>
|
|
(binding ...)<br>
|
|
body1 body2 ...))))<br>
|
|
<br>
|
|
(define-syntax let-values-helper1<br>
|
|
;; map over the bindings<br>
|
|
(syntax-rules ()<br>
|
|
((let-values<br>
|
|
((id temp) ...)<br>
|
|
()<br>
|
|
body1 body2 ...)<br>
|
|
(let ((id temp) ...) body1 body2 ...))<br>
|
|
((let-values<br>
|
|
assocs<br>
|
|
((formals1 expr1) (formals2 expr2) ...)<br>
|
|
body1 body2 ...)<br>
|
|
(let-values-helper2<br>
|
|
formals1<br>
|
|
()<br>
|
|
expr1<br>
|
|
assocs<br>
|
|
((formals2 expr2) ...)<br>
|
|
body1 body2 ...))))<br>
|
|
<br>
|
|
(define-syntax let-values-helper2<br>
|
|
;; create temporaries for the formals<br>
|
|
(syntax-rules ()<br>
|
|
((let-values-helper2<br>
|
|
()<br>
|
|
temp-formals<br>
|
|
expr1<br>
|
|
assocs<br>
|
|
bindings<br>
|
|
body1 body2 ...)<br>
|
|
(call-with-values<br>
|
|
(lambda () expr1)<br>
|
|
(lambda temp-formals<br>
|
|
(let-values-helper1<br>
|
|
assocs<br>
|
|
bindings<br>
|
|
body1 body2 ...))))<br>
|
|
((let-values-helper2<br>
|
|
(first . rest)<br>
|
|
(temp ...)<br>
|
|
expr1<br>
|
|
(assoc ...)<br>
|
|
bindings<br>
|
|
body1 body2 ...)<br>
|
|
(let-values-helper2<br>
|
|
rest<br>
|
|
(temp ... newtemp)<br>
|
|
expr1<br>
|
|
(assoc ... (first newtemp))<br>
|
|
bindings<br>
|
|
body1 body2 ...))<br>
|
|
((let-values-helper2<br>
|
|
rest-formal<br>
|
|
(temp ...)<br>
|
|
expr1<br>
|
|
(assoc ...)<br>
|
|
bindings<br>
|
|
body1 body2 ...)<br>
|
|
(call-with-values<br>
|
|
(lambda () expr1)<br>
|
|
(lambda (temp ... . newtemp)<br>
|
|
(let-values-helper1<br>
|
|
(assoc ... (rest-formal newtemp))<br>
|
|
bindings<br>
|
|
body1 body2 ...))))))<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_43"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_43"><tt>let*-values</tt></a></h4>
|
|
<p>The following macro defines <tt>let*-values</tt> in terms of <tt>let</tt>
|
|
and <tt>let-values</tt> using <tt>syntax-rules</tt>:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax let*-values<br>
|
|
(syntax-rules ()<br>
|
|
((let*-values () body1 body2 ...)<br>
|
|
(let () body1 body2 ...))<br>
|
|
((let*-values (binding1 binding2 ...)<br>
|
|
body1 body2 ...)<br>
|
|
(let-values (binding1)<br>
|
|
(let*-values (binding2 ...)<br>
|
|
body1 body2 ...)))))<p></tt></p>
|
|
<p>
|
|
</p>
|
|
<a name="node_sec_Temp_44"></a>
|
|
<h4 class=section><a href="r6rs-Z-H-2.html#node_toc_node_sec_Temp_44"><tt>let</tt></a></h4>
|
|
<p>The <tt>let</tt> keyword could be defined in terms of <tt>lambda</tt> and <tt>letrec</tt>
|
|
using <tt>syntax-rules</tt> as
|
|
follows:</p>
|
|
<p>
|
|
</p>
|
|
|
|
<tt>(define-syntax <tt>let</tt><br>
|
|
(syntax-rules ()<br>
|
|
((let ((name val) ...) body1 body2 ...)<br>
|
|
((lambda (name ...) body1 body2 ...)<br>
|
|
val ...))<br>
|
|
((let tag ((name val) ...) body1 body2 ...)<br>
|
|
((letrec ((tag (lambda (name ...)<br>
|
|
body1 body2 ...)))<br>
|
|
tag)<br>
|
|
val ...))))<p></tt></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.html">first</a>, <a href="r6rs-Z-H-15.html">previous</a></span><span>, <a href="r6rs-Z-H-17.html">next</a></span> page<span>; </span><span><a href="r6rs-Z-H-2.html#node_toc_start">contents</a></span><span><span>; </span><a href="r6rs-Z-H-21.html#node_index_start">index</a></span>]</div>
|
|
</p>
|
|
<p></p>
|
|
</div>
|
|
</body>
|
|
</html>
|