psyntax-website/www/old-psyntax.html

546 lines
19 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"><!-- DO NOT EDIT THIS FILE-->
<!-- Edit the .tex version instead-->
<html>
<head>
<title>Pre-R6RS Portable syntax-case</title>
</head>
<body>
<h1 >Pre-R6RS Portable syntax-case</h1>
<p>
<a href="//legacy.cs.indiana.edu/~dyb/">R. Kent Dybvig</a>,
Oscar Waddell
<p>
The syntax-case macro system implements the restricted high-level
<tt>syntax-rules</tt> macros of the Revised<sup>5</sup> Report
as well as the equally high-level but general-purpose
<tt>syntax-case</tt> macros.
It also supports a compatible module system that allows import and
export of macro bindings as well as bindings for variables and
modules.
<p>
The system is documented in Section&nbsp;3.1 and Chapter&nbsp;8 of
<a href="//www.scheme.com/tspl3/">The Scheme Programming
Language, third edition</a> and in Chapter 9 of the
<a href="//www.scheme.com/csug7/">Chez Scheme Version 7 User's
Guide</a>.
The former has more introductory material and examples, while the
latter documents some
aspects of the system not covered by the former.
<p>
Aspects of the system and its implementation are described in
<a href="//legacy.cs.indiana.edu/~dyb/pubs/LaSC-5-4-pp295-326-abstract.html">Syntactic
abstraction in Scheme</a>
and
<a href="//legacy.cs.indiana.edu/~dyb/pubs/popl99-abstract.html">Extending
the Scope of Syntactic Abstraction</a>
Additional examples of its use are given in
<a href="//legacy.cs.indiana.edu/~dyb/pubs/tr356-abstract.html">Writing
hygienic macros in Scheme with syntax-case</a>.
<p>
The portable system is designed to be adaptable with minimal effort to
any Revised<sup>5</sup> Report implementation of Scheme, with the
provision of a small set of implementation-dependent hooks to install
the expander.
Included with the portable expander are definitions of each of the
syntactic forms supported by the Revised<sup>5</sup> Report.
Along with a reader, the system forms a complete front-end for Scheme.
If the reader and evaluator support source annotations (e.g., file
and line number information), these are handled as well to provide
source-object correlation.
<p>
The portable syntax-case implementation consists of one file,
<a href="//files.scheme.org/psyntax-7.3.ss">psyntax.ss</a>.
The file <a href="//files.scheme.org/psyntax-7.3.pp">psyntax.pp</a> is
an expanded version of the file that may be used for bootstrapping
the system.
See the porting notes in psyntax.ss
<p>
Please let us know if you successfully port this code to a new Scheme
implementation, and also please allow us to include the hooks you
develop in doing the port in this directory for use by others.
<p>
Please also contact us if you have difficulty porting to a new Scheme
implementation or if you discover that the implementation depends on
nonportable features of Chez Scheme in some undocumented way.
<p>
<h2>Release Notes</h2>
<p>
Version numbers refer to the version of Chez Scheme from which the
portable version was extracted.
<p>
<h3>Version 7.3 (2/26/2007)</h3>
<p>
[<a href="//files.scheme.org/psyntax-7.3.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-7.3.pp">psyntax.pp</a>]
<p>
<ul>
<li>The <tt>quasiquote</tt> form now guarantees that new pairs or vectors
will be allocated any time a nonempty <tt>unquote</tt> or
<tt>unquote-splicing</tt> form is used, even if the unquoted object
is itself a constant.
For example, while <tt>`(a&nbsp;.&nbsp;b)</tt> is equivalent to <tt>'(a&nbsp;.&nbsp;b)</tt>
and returns a constant pair (the same one each time the
<tt>quasiquote</tt> expression is evaluated, e.g., in a loop or procedure
called multiple times) <tt>`(,'a&nbsp;.&nbsp;,'b)</tt> is equivalent to
<tt>(cons&nbsp;'a&nbsp;'b)</tt> so that a new pair is allocated each time the
<tt>quasiquote</tt> expression is evaluated.
<p>
<li>The <tt>generate-temporaries</tt> procedure no longer creates a
gensym but instead creates an ordinary symbol.
The symbols differ in name one from each other over the course of a
run and are given a special "tmp" mark to distinguish them from
other identifiers.
</ul>
<p>
<p>
<h3>Version 7.1 (8/1/2006)</h3>
<p>
[<a href="//files.scheme.org/psyntax-7.1.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-7.1.pp">psyntax.pp</a>]
<p>
<ul>
<li><tt>syntax</tt> now disallows vectors starting with an
ellipsis, e.g., <tt>#'#(...&nbsp;foo)</tt>.
<p>
<li>A new <tt>syntax-&gt;vector</tt> procedure, similar to <tt>syntax-&gt;list</tt>
has been added.
<p>
<li>Support for <tt>quasisyntax</tt>, <tt>unsyntax</tt>, and
<tt>unsyntax-splicing</tt> forms has been added.
Implementations are encouraged to supply hash-backquote
(&nbsp;<tt>#`</tt>&nbsp;), hash-comma (&nbsp;<tt>#,</tt>&nbsp;), and
hash-comma-at (&nbsp;<tt>#,@</tt>&nbsp;) abbreviations for the three new forms.
</ul>
<p>
<p>
<h3>Version 7.0 (9/2/2005)</h3>
<p>
[<a href="//files.scheme.org/psyntax-7.0.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-7.0.pp">psyntax.pp</a>]
<p>
<ul>
<li><tt>quasiquote</tt> now leaves <tt>unquote</tt> untouched in
<tt>`#(a&nbsp;...&nbsp;unqoute&nbsp;b)</tt> rather than trying to treat it as the
equivalent of <tt>(list-&gt;vector&nbsp;`(a&nbsp;...&nbsp;.&nbsp;(unquote&nbsp;b)))</tt>.
<p>
<li>Some portability problems have been eliminated:
<tt>#4(---)</tt> in <tt>syntax-case</tt> is now <tt>#(---)</tt>;
a <tt>format</tt> call has been replaced with a call to
<tt>symbol-&gt;string</tt>; a call to <tt>list*</tt> has been
replaced with a <tt>quasiquote</tt> form;
<tt>remq</tt> is now defined where it is used (<tt>update-mode-set</tt>);
and dummy definitions have been added (but are commented out) for the
variables defined (assigned) by the system for implementations that
require them.
<p>
<li><tt>syntax-rules</tt> now allows fenders.
<p>
<li>Two new derived forms, <tt>with-implicit</tt> and <tt>datum</tt>,
and one new procedure, <tt>syntax-&gt;list</tt>, have been added.
See the <a href="//www.scheme.com/csug7/">Chez Scheme Version 7 User's Guide</a>
for descriptions.
<p>
<li><tt>import-only</tt> at top level is officially treated as an
<tt>import</tt>.
<p>
<li>An identifier <tt><i>x</i></tt> imported from a module <tt><i>m</i></tt> is now treated
in the importing context as if the corresponding export identifier had
been present in the import form along with <tt><i>m</i></tt>.
See the <a href="//www.scheme.com/csug7/">Chez Scheme Version 7 User's Guide</a>
for a description of the now current <tt>import</tt> semantics.
</ul>
<p>
<p>
<h3>Version 6.9c (9/2/2004)</h3>
<p>
[<a href="//files.scheme.org/psyntax-6.9c.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-6.9c.pp">psyntax.pp</a>]
<p>
<ul>
<li>Added a meta prefix for definitions that tells the expander that
any variable definition resulting from the definition is to be an
expand-time definition available only on the right-hand sides of other
meta definitions and, most importantly, to transformer expressions.
It is used to define expand-time helpers and other information for use
by one or more <tt>syntax-case</tt> transformers.
See the comments in the code for examples of its use.
<p>
<li>Added a new definition form <tt>alias</tt> which
may be used to create aliases from one identifier to another.
<tt>(alias&nbsp;<i>new-id</i>&nbsp;<i>old-id</i>)</tt> makes
<tt><i>new-id</i></tt> behave like <tt><i>old-id</i></tt>.
It is implemented by mapping <tt>new-id</tt>
to the same label, which may be <tt><i>old-id</i></tt> itself if <tt><i>old-id</i></tt>
is a top-level identifier.
(This feature was added to support the new <tt>import</tt> syntax
below.)
<p>
<li>Extended the syntax of <tt>import</tt> to allow for selection and
renaming of imports.
An <tt>import</tt> form now has the following syntax:
<p>
<p><tt>(import&nbsp;<i>spec</i>&nbsp;...)</tt>
<p>Where <tt><i>spec</i></tt> is defined by the following grammar:
<p>
<TABLE><TR><TD nowrap align="left">
<i>spec</i></TD><TD nowrap align="center">=</TD><TD nowrap align="left"><i>id</i></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(only</tt> <i>spec</i> <i>id</i>*<tt>)</tt></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(except</tt> <i>spec</i> <i>id</i>*<tt>)</tt></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(add-prefix</tt> <i>spec</i> <i>id</i><tt>)</tt></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(drop-prefix</tt> <i>spec</i> <i>id</i><tt>)</tt></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(rename</tt> <i>spec</i> (<i>new-id</i> <i>old-id</i>)*<tt>)</tt></TD></TR><TR><TD nowrap align="left">
</TD><TD nowrap align="center">|</TD><TD nowrap align="left"><tt>(alias</tt> <i>spec</i> (<i>new-id</i> <i>old-id</i>)*<tt>)</tt>
</TD></TR></TABLE>
<p>
<tt>only</tt> imports only the listed identifiers;
<tt>except</tt> imports all but the listed identifiers;
<tt>add-prefix</tt> adds the given prefix to the imports;
<tt>drops-prefix</tt> drops the given prefix to the imports, which must
all share the given prefix;
rename provides new names for the listed imports; and
alias provides additional names for the listed imports.
<p>
<li>Eliminated separate per-body-form <tt>r</tt> and <tt>mr</tt> and with
them the need to destructively update environments.
The per-body-form <tt>r</tt> and <tt>mr</tt> did nothing more than control
the extent of <tt>let-syntax</tt>/<tt>letrec-syntax</tt> bindings to
prevent things like
<p>
<p><tt>(let&nbsp;()<br>
&nbsp;&nbsp;(let-syntax&nbsp;((a&nbsp;(identifier-syntax&nbsp;3)))<br>
&nbsp;&nbsp;&nbsp;&nbsp;(define-syntax&nbsp;b&nbsp;(identifier-syntax&nbsp;a)))<br>
&nbsp;&nbsp;b)</tt>
<p>where <tt>a</tt> is not actually run until expand-time control has left the
<tt>let-syntax</tt> form.
This kind of thing is harmless, though, and in any case, <tt>a</tt> is
visible only within the body of the <tt>let-syntax</tt> form by virtue of the
wrap.
<p>
<li>Replaced some uses of continuation-passing style in the <tt>chi</tt>
and <tt>parse</tt> procedures.
<p>
<li>Cleaned up chi-top-module.
</ul>
<p>
<p>
<h3>Version 6.9a (5/13/2003)</h3>
<p>
[<a href="//files.scheme.org/psyntax-6.9a.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-6.9a.pp">psyntax.pp</a>]
<p>
<ul>
<li>Made several modifications to support environments.
Changed name of <tt>put-global-definition-hook</tt> to
<tt>put-cte-hook</tt>.
Added new <tt>put-global-definition-hook</tt> that actually
does what you'd expect, i.e., install a binding that can be
retrieved by <tt>get-global-definition-hook</tt>.
Added third <tt><i>top-token</i></tt> argument to both <tt>$sc-put-cte</tt>
and <tt>build-cte-install</tt>,
identifying the top-level environment into which the binding
should be installed.
Added new <tt>read-only-binding?</tt> hook that can be used to
identify bindings that are read only (currently always returns false).
Added <tt>put-import-binding</tt>, which installs bindings
that can be retrieved by <tt>get-import-binding</tt>.
<p>
<li>The new user-visible environment features are an <tt>environment?</tt>
predicate and <tt>interaction-environment</tt>.
Another new procedure, <tt>$make-environment</tt>, is also defined
by the system but is intended as a low-level feature to be
used by the host implementation to define other environments, such as
<tt>ieee</tt>, <tt>scheme-report</tt>, and <tt>null</tt>,
and possibly even user-defined environments, that are not directly
supported by the portable <tt>syntax-case</tt> expander.
<p>
<li><tt>import-only</tt> is now supported at top level.
<p>
<li><tt>define-syntax</tt> now supports the "defun" syntax, e.g.:
<p>
<p><tt>(define-syntax&nbsp;(foo&nbsp;x)&nbsp;(syntax-case&nbsp;x&nbsp;---))</tt>
<p><li><tt>module</tt>, <tt>import</tt>, and <tt>import-only</tt>
are now macros that expand into
<tt>$module</tt>, <tt>$import</tt>, and <tt>$import-only</tt>.
This change was made primarily to simplify the expander by moving the
handling of anonymous modules into the macro versions.
<p>
<li>The build procedures, e.g., <tt>build-application</tt>,
now receive the entire annotated expression rather than just the source
extracted from the source annotation.
Along with this change,
renamed <tt>source</tt>, <tt>src</tt> and <tt>s</tt>
to <tt>ae</tt>
(for annotated expression) in many places, since the object passed
around is now the annotated expression rather than the source
extracted from the annotated expression.
<tt>annotation-stripped</tt> is now expected to return the stripped version
of an annotated expression, i.e., <tt>strip-annotation</tt> simply
grabs for the stripped version rather than traversing the (possibly
cyclic) annotated expression.
<p>
<li>Added a new <tt>built-lambda?</tt> predicate that is used to recognize
<tt>lambda</tt> expressions built by <tt>build-lambda</tt>.
(This is used in handling deferred transformer bindings; see below.)
<p>
<li>Modified <tt>build-begin</tt> to weed out leading calls to
<tt>void</tt> and suppress the <tt>begin</tt> wrapper when
only one subexpression is present.
It assumes built <tt>void</tt> calls are represented as ordinary
s-expressions; change this if your <tt>build-application</tt>
uses some other representation for applications.
<p>
<li><tt>make-binding</tt> now builds quoted structure if type is
known and value is false.
<p>
<li><tt>transformer-env</tt> now strips out syntax variables, as it
should have been doing all along.
<p>
<li>So we can't be caught being lazy, we defer the evaluation of a
local transformer only if it is a <tt>lambda</tt> expression.
</ul>
<p>
<p>
<h3>Version 6.9 (7/12/2002)</h3>
<p>
[<a href="//files.scheme.org/psyntax-6.9.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-6.9.pp">psyntax.pp</a>]
<p>
<ul>
<li>Changed <tt>chi-top-module</tt> so that definitions and initialization
forms in compiled files are not evaluated (by default) at visit time.
<p>
<li>Recoded <tt>generate-id</tt> so that generated symbols have a
standard print representation and to avoid ASCII dependencies.
<p>
<li>Extended the syntax of <tt>syntax-case</tt> patterns to allow a
fixed number of items after an ellipsis.
Ellipses are therefore no longer constrained to appear only at the end
of a list- or vector-structured form, but only one ellipsis can appear
at a given level of a list- or vector-structured form.
For example, <tt>(a&nbsp;...&nbsp;b)</tt> matches a list of one or more
elements, with <tt>b</tt> bound to the last element and
<tt>a&nbsp;...</tt> to all but the last element.
<p>
<li>Added a local definition for a one-clause version of <tt>let-values</tt>
and recoded uses of <tt>call-with-values</tt> using
<tt>let-values</tt>.
<p>
<li>Fixed two bugs in the portable expander.
One resulted in an error in <tt>vector-ref</tt> when redefining
a variable at top level that was previously imported from a module.
The other caused the wrong identifier to be exported in certain
circumstances, perhaps resulting in an inappropriate identifier out of
context error.
</ul>
<p>
<p>
<h3>Version 6.8 (2/6/2002)</h3>
<p>
[<a href="//files.scheme.org/psyntax-6.8.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-6.8.pp">psyntax.pp</a>]
<p>
<ul>
<li>Added support for <tt>visit</tt> and <tt>revisit</tt> procedures,
which are relevant for systems that support <tt>compile-file</tt>:
<tt>visit</tt> is like <tt>load</tt> but loads only compile-time
information, and <tt>revisit</tt> is like <tt>load</tt> but loads
only run-time information.
<p>
<li>Cleaned up and extended <tt>eval-when</tt> to handle new situations
<tt>visit</tt> and <tt>revisit</tt>.
A translation table that clearly shows what happens with nested
<tt>eval-when</tt> forms is given in the source.
<p>
<li>Added <tt>literal-identifier=?</tt>.
<tt>literal-identifier=?</tt> is similar to
<tt>free-identifier=?</tt> except that the former equates
top-level identifiers that come from different modules, even if they
do not necessarily resolve to the same binding.
<tt>syntax-rules</tt> and <tt>syntax-case</tt> employ
literal-identifier=? to compare identifiers listed in the literals list
against input identifiers.
<tt>literal-identifier=?</tt> is intended for the
comparison of auxiliary keywords such as
<tt>else</tt> in <tt>cond</tt> and <tt>case</tt>, where
no actual binding is involved.
<p>
<li>Fixed a bug in the portable expander that caused an application of
<tt>cdr</tt> to the empty list in <tt>build-sequence</tt>
for top-level modules with no exported definitions other than
reexports, e.g.,
<p>
<p><tt>(module&nbsp;m1&nbsp;(a)&nbsp;(define&nbsp;a&nbsp;3))<br>
(module&nbsp;m2&nbsp;(a)&nbsp;(import&nbsp;m1))<br>
(let&nbsp;()&nbsp;(import&nbsp;m2)&nbsp;a)&nbsp;&rarr;&nbsp;3</tt>
<p><li>Fixed a bug in the portable expander that prevented use of "hidden"
top-level definitions in the output of a macro, e.g.:
<p>
<p><tt>(define-syntax&nbsp;counter<br>
&nbsp;&nbsp;(syntax-rules&nbsp;()<br>
&nbsp;&nbsp;&nbsp;&nbsp;((_&nbsp;ref&nbsp;incr&nbsp;e)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(begin<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(define&nbsp;hidden&nbsp;e)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(define&nbsp;ref&nbsp;(lambda&nbsp;()&nbsp;hidden))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(define&nbsp;incr&nbsp;(lambda&nbsp;(n)&nbsp;(set!&nbsp;hidden&nbsp;(+&nbsp;hidden&nbsp;n))))))))<br>
(counter&nbsp;get&nbsp;bump&nbsp;17)<br>
(get)&nbsp;&rarr;&nbsp;17<br>
(bump&nbsp;4)<br>
(get)&nbsp;&rarr;&nbsp;21<br>
hidden&nbsp;&rarr;&nbsp;unbound&nbsp;error</tt>
<p><li>An incompatible change to the expander has been
made to reduce the loss of source information when one macro generates
another macro definition: List and vector structure in the subexpression
of a syntax form is no longer guaranteed to be list and vector structure
in the output form except where pattern variables are contained within
that structure.
For example, <tt>#'(a&nbsp;...)</tt>, where <tt>a</tt> is a pattern
variable, is guaranteed to evaluate to a list, but the constant
structure <tt>(a&nbsp;b&nbsp;c&nbsp;d)</tt>, none of <tt>a</tt>, <tt>b</tt>,
<tt>c</tt>, and <tt>d</tt> are pattern variables, may not.
The practical consequence of this change is that constant
structures must be deconstructed using <tt>syntax-case</tt> or
<tt>syntax-rules</tt> rather than <tt>car</tt>, <tt>cdr</tt>,
and other list-processing operations.
</ul>
<p>
<p>
<h3>Version 6.3 (8/30/2000)</h3>
<p>
[<a href="//files.scheme.org/psyntax-6.3.ss">psyntax.ss</a>,
<a href="//files.scheme.org/psyntax-6.3.pp">psyntax.pp</a>]
<p>
<ul>
<li>The portable syntax-case macro system is now up-to-date with respect to
<a href="//www.scheme.com/tspl2/">The Scheme Programming
Language, second edition</a> and the
<a href="//www.scheme.com/csug6/">Chez Scheme User's
Guide</a>.
</ul>
<p>
<p>
<p>
</body>
</html>