diff options
Diffstat (limited to 'slib_3.html')
-rw-r--r-- | slib_3.html | 2013 |
1 files changed, 0 insertions, 2013 deletions
diff --git a/slib_3.html b/slib_3.html deleted file mode 100644 index 0f0e6e9..0000000 --- a/slib_3.html +++ /dev/null @@ -1,2013 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" - "http://www.w3.org/TR/html40/loose.dtd"> -<HTML> -<!-- Created on January, 10 2005 by texi2html 1.66 --> -<!-- -Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) - Karl Berry <karl@freefriends.org> - Olaf Bachmann <obachman@mathematik.uni-kl.de> - and many others. -Maintained by: Many creative people <dev@texi2html.cvshome.org> -Send bugs and suggestions to <users@texi2html.cvshome.org> - ---> -<HEAD> -<TITLE>SLIB: Scheme Syntax Extension Packages</TITLE> - -<META NAME="description" CONTENT="SLIB: Scheme Syntax Extension Packages"> -<META NAME="keywords" CONTENT="SLIB: Scheme Syntax Extension Packages"> -<META NAME="resource-type" CONTENT="document"> -<META NAME="distribution" CONTENT="global"> -<META NAME="Generator" CONTENT="texi2html 1.66"> - -</HEAD> - -<BODY LANG="en" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"> - -<A NAME="SEC21"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_2.html#SEC20"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC22"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_2.html#SEC13"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H1> 3. Scheme Syntax Extension Packages </H1> -<!--docid::SEC21::--> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC22">3.1 Defmacro</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Supported by all implementations</TD></TR> -<TR><TH COLSPAN="3" ALIGN="left" VALIGN="TOP"> -</TH></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC24">3.2 R4RS Macros</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'macro</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC25">3.3 Macro by Example</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'macro-by-example</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC27">3.4 Macros That Work</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'macros-that-work</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC30">3.5 Syntactic Closures</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'syntactic-closures</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC36">3.6 Syntax-Case Macros</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'syntax-case</TD></TR> -<TR><TH COLSPAN="3" ALIGN="left" VALIGN="TOP"> -</TH></TR> -<TR><TH COLSPAN="3" ALIGN="left" VALIGN="TOP">Syntax extensions (macros) included with SLIB. -</TH></TR> -<TR><TH COLSPAN="3" ALIGN="left" VALIGN="TOP"> -</TH></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC39">3.7 Fluid-Let</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'fluid-let</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC40">3.8 Yasos</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'yasos, 'oop, 'collect</TD></TR> -</TABLE> -<P> - -<A NAME="Defmacro"></A> -<HR SIZE="6"> -<A NAME="SEC22"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC23"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.1 Defmacro </H2> -<!--docid::SEC22::--> -<P> - -Defmacros are supported by all implementations. -</P> -<P> - -<A NAME="IDX107"></A> -</P> -<DL> -<DT><U>Function:</U> <B>gentemp</B> -<DD>Returns a new (interned) symbol each time it is called. The symbol -names are implementation-dependent -<TABLE><tr><td> </td><td class=example><pre>(gentemp) => scm:G0 -(gentemp) => scm:G1 -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX108"></A> -</P> -<DL> -<DT><U>Function:</U> <B>defmacro:eval</B> <I>e</I> -<DD>Returns the <CODE>slib:eval</CODE> of expanding all defmacros in scheme -expression <VAR>e</VAR>. -</DL> -<P> - -<A NAME="IDX109"></A> -</P> -<DL> -<DT><U>Function:</U> <B>defmacro:load</B> <I>filename</I> -<DD><VAR>filename</VAR> should be a string. If filename names an existing file, -the <CODE>defmacro:load</CODE> procedure reads Scheme source code expressions -and definitions from the file and evaluates them sequentially. These -source code expressions and definitions may contain defmacro -definitions. The <CODE>macro:load</CODE> procedure does not affect the values -returned by <CODE>current-input-port</CODE> and -<CODE>current-output-port</CODE>. -</DL> -<P> - -<A NAME="IDX110"></A> -</P> -<DL> -<DT><U>Function:</U> <B>defmacro?</B> <I>sym</I> -<DD>Returns <CODE>#t</CODE> if <VAR>sym</VAR> has been defined by <CODE>defmacro</CODE>, -<CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX111"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macroexpand-1</B> <I>form</I> -<DD><A NAME="IDX112"></A> -<DT><U>Function:</U> <B>macroexpand</B> <I>form</I> -<DD>If <VAR>form</VAR> is a macro call, <CODE>macroexpand-1</CODE> will expand the -macro call once and return it. A <VAR>form</VAR> is considered to be a macro -call only if it is a cons whose <CODE>car</CODE> is a symbol for which a -<CODE>defmacro</CODE> has been defined. -<P> - -<CODE>macroexpand</CODE> is similar to <CODE>macroexpand-1</CODE>, but repeatedly -expands <VAR>form</VAR> until it is no longer a macro call. -</P> -</DL> -<P> - -<A NAME="IDX113"></A> -</P> -<DL> -<DT><U>Macro:</U> <B>defmacro</B> <I>name lambda-list form <small>...</small></I> -<DD>When encountered by <CODE>defmacro:eval</CODE>, <CODE>defmacro:macroexpand*</CODE>, -or <CODE>defmacro:load</CODE> defines a new macro which will henceforth be -expanded when encountered by <CODE>defmacro:eval</CODE>, -<CODE>defmacro:macroexpand*</CODE>, or <CODE>defmacro:load</CODE>. -</DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC23"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC22"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC24"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.1.1 Defmacroexpand </H3> -<!--docid::SEC23::--> -<CODE>(require 'defmacroexpand)</CODE> -<A NAME="IDX114"></A> -<P> - -<A NAME="IDX115"></A> -</P> -<DL> -<DT><U>Function:</U> <B>defmacro:expand*</B> <I>e</I> -<DD>Returns the result of expanding all defmacros in scheme expression -<VAR>e</VAR>. -</DL> -<P> - -<A NAME="R4RS Macros"></A> -<HR SIZE="6"> -<A NAME="SEC24"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC23"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC25"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.2 R4RS Macros </H2> -<!--docid::SEC24::--> -<P> - -<CODE>(require 'macro)</CODE> is the appropriate call if you want R4RS -<A NAME="IDX116"></A> -high-level macros but don't care about the low level implementation. If -an SLIB R4RS macro implementation is already loaded it will be used. -Otherwise, one of the R4RS macros implemetations is loaded. -</P> -<P> - -The SLIB R4RS macro implementations support the following uniform -interface: -</P> -<P> - -<A NAME="IDX117"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:expand</B> <I>sexpression</I> -<DD>Takes an R4RS expression, macro-expands it, and returns the result of -the macro expansion. -</DL> -<P> - -<A NAME="IDX118"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:eval</B> <I>sexpression</I> -<DD>Takes an R4RS expression, macro-expands it, evals the result of the -macro expansion, and returns the result of the evaluation. -</DL> -<P> - -<A NAME="IDX119"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>macro:load</B> <I>filename</I> -<DD><VAR>filename</VAR> should be a string. If filename names an existing file, -the <CODE>macro:load</CODE> procedure reads Scheme source code expressions and -definitions from the file and evaluates them sequentially. These source -code expressions and definitions may contain macro definitions. The -<CODE>macro:load</CODE> procedure does not affect the values returned by -<CODE>current-input-port</CODE> and <CODE>current-output-port</CODE>. -</DL> -<P> - -<A NAME="Macro by Example"></A> -<HR SIZE="6"> -<A NAME="SEC25"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC24"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC26"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.3 Macro by Example </H2> -<!--docid::SEC25::--> -<P> - -<CODE>(require 'macro-by-example)</CODE> -<A NAME="IDX120"></A> -</P> -<P> - -A vanilla implementation of <CITE>Macro by Example</CITE> (Eugene Kohlbecker, -R4RS) by Dorai Sitaram, (dorai @ cs.rice.edu) using <CODE>defmacro</CODE>. -</P> -<P> - -<UL> - -<LI> -generating hygienic global <CODE>define-syntax</CODE> Macro-by-Example macros -<STRONG>cheaply</STRONG>. -<P> - -</P> -<LI> -can define macros which use <CODE>...</CODE>. -<P> - -</P> -<LI> -needn't worry about a lexical variable in a macro definition -clashing with a variable from the macro use context -<P> - -</P> -<LI> -don't suffer the overhead of redefining the repl if <CODE>defmacro</CODE> -natively supported (most implementations) -<P> - -</UL> -<HR SIZE="6"> -<A NAME="SEC26"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC25"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC27"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.3.1 Caveat </H3> -<!--docid::SEC26::--> -These macros are not referentially transparent (see section `Macros' in <CITE>Revised(4) Scheme</CITE>). Lexically scoped macros (i.e., <CODE>let-syntax</CODE> -and <CODE>letrec-syntax</CODE>) are not supported. In any case, the problem -of referential transparency gains poignancy only when <CODE>let-syntax</CODE> -and <CODE>letrec-syntax</CODE> are used. So you will not be courting -large-scale disaster unless you're using system-function names as local -variables with unintuitive bindings that the macro can't use. However, -if you must have the full <CITE>r4rs</CITE> macro functionality, look to the -more featureful (but also more expensive) versions of syntax-rules -available in slib <A HREF="slib_3.html#SEC27">3.4 Macros That Work</A>, <A HREF="slib_3.html#SEC30">3.5 Syntactic Closures</A>, and -<A HREF="slib_3.html#SEC36">3.6 Syntax-Case Macros</A>. -<P> - -<A NAME="IDX121"></A> -</P> -<DL> -<DT><U>Macro:</U> <B>define-syntax</B> <I>keyword transformer-spec</I> -<DD>The <VAR>keyword</VAR> is an identifier, and the <VAR>transformer-spec</VAR> -should be an instance of <CODE>syntax-rules</CODE>. -<P> - -The top-level syntactic environment is extended by binding the -<VAR>keyword</VAR> to the specified transformer. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-syntax let* - (syntax-rules () - ((let* () body1 body2 ...) - (let () body1 body2 ...)) - ((let* ((name1 val1) (name2 val2) ...) - body1 body2 ...) - (let ((name1 val1)) - (let* (( name2 val2) ...) - body1 body2 ...))))) -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX122"></A> -</P> -<DL> -<DT><U>Macro:</U> <B>syntax-rules</B> <I>literals syntax-rule <small>...</small></I> -<DD><VAR>literals</VAR> is a list of identifiers, and each <VAR>syntax-rule</VAR> -should be of the form -<P> - -<CODE>(<VAR>pattern</VAR> <VAR>template</VAR>)</CODE> -</P> -<P> - -where the <VAR>pattern</VAR> and <VAR>template</VAR> are as in the grammar above. -</P> -<P> - -An instance of <CODE>syntax-rules</CODE> 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 -<CODE>syntax-rules</CODE> is matched against the patterns contained in the -<VAR>syntax-rule</VAR>s, beginning with the leftmost <VAR>syntax-rule</VAR>. -When a match is found, the macro use is trancribed hygienically -according to the template. -</P> -<P> - -Each pattern begins with the keyword for the macro. This keyword is not -involved in the matching and is not considered a pattern variable or -literal identifier. -</P> -</DL> -<P> - -<A NAME="Macros That Work"></A> -<HR SIZE="6"> -<A NAME="SEC27"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC26"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC28"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.4 Macros That Work </H2> -<!--docid::SEC27::--> -<P> - -<CODE>(require 'macros-that-work)</CODE> -<A NAME="IDX123"></A> -</P> -<P> - -<CITE>Macros That Work</CITE> differs from the other R4RS macro -implementations in that it does not expand derived expression types to -primitive expression types. -</P> -<P> - -<A NAME="IDX124"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:expand</B> <I>expression</I> -<DD><A NAME="IDX125"></A> -<DT><U>Function:</U> <B>macwork:expand</B> <I>expression</I> -<DD>Takes an R4RS expression, macro-expands it, and returns the result of -the macro expansion. -</DL> -<P> - -<A NAME="IDX126"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:eval</B> <I>expression</I> -<DD><A NAME="IDX127"></A> -<DT><U>Function:</U> <B>macwork:eval</B> <I>expression</I> -<DD><CODE>macro:eval</CODE> returns the value of <VAR>expression</VAR> in the current -top level environment. <VAR>expression</VAR> can contain macro definitions. -Side effects of <VAR>expression</VAR> will affect the top level -environment. -</DL> -<P> - -<A NAME="IDX128"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>macro:load</B> <I>filename</I> -<DD><A NAME="IDX129"></A> -<DT><U>Procedure:</U> <B>macwork:load</B> <I>filename</I> -<DD><VAR>filename</VAR> should be a string. If filename names an existing file, -the <CODE>macro:load</CODE> procedure reads Scheme source code expressions and -definitions from the file and evaluates them sequentially. These source -code expressions and definitions may contain macro definitions. The -<CODE>macro:load</CODE> procedure does not affect the values returned by -<CODE>current-input-port</CODE> and <CODE>current-output-port</CODE>. -</DL> -<P> - -References: -</P> -<P> - -The <CITE>Revised^4 Report on the Algorithmic Language Scheme</CITE> Clinger -and Rees [editors]. To appear in LISP Pointers. Also available as a -technical report from the University of Oregon, MIT AI Lab, and -Cornell. -</P> -<P> - -<center> - Macros That Work. Clinger and Rees. POPL '91. -</center> -</P> -<P> - -The supported syntax differs from the R4RS in that vectors are allowed -as patterns and as templates and are not allowed as pattern or template -data. -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>transformer spec ==> (syntax-rules literals rules) - -rules ==> () - | (rule . rules) - -rule ==> (pattern template) - -pattern ==> pattern_var ; a symbol not in literals - | symbol ; a symbol in literals - | () - | (pattern . pattern) - | (ellipsis_pattern) - | #(pattern*) ; extends R4RS - | #(pattern* ellipsis_pattern) ; extends R4RS - | pattern_datum - -template ==> pattern_var - | symbol - | () - | (template2 . template2) - | #(template*) ; extends R4RS - | pattern_datum - -template2 ==> template - | ellipsis_template - -pattern_datum ==> string ; no vector - | character - | boolean - | number - -ellipsis_pattern ==> pattern ... - -ellipsis_template ==> template ... - -pattern_var ==> symbol ; not in literals - -literals ==> () - | (symbol . literals) -</pre></td></tr></table><P> - -<HR SIZE="6"> -<A NAME="SEC28"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC27"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC29"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.4.1 Definitions </H3> -<!--docid::SEC28::--> -<P> - -</P> -<DL COMPACT> - -<DT>Scope of an ellipsis -<DD>Within a pattern or template, the scope of an ellipsis (<CODE>...</CODE>) is -the pattern or template that appears to its left. -<P> - -</P> -<DT>Rank of a pattern variable -<DD>The rank of a pattern variable is the number of ellipses within whose -scope it appears in the pattern. -<P> - -</P> -<DT>Rank of a subtemplate -<DD>The rank of a subtemplate is the number of ellipses within whose scope -it appears in the template. -<P> - -</P> -<DT>Template rank of an occurrence of a pattern variable -<DD>The template rank of an occurrence of a pattern variable within a -template is the rank of that occurrence, viewed as a subtemplate. -<P> - -</P> -<DT>Variables bound by a pattern -<DD>The variables bound by a pattern are the pattern variables that appear -within it. -<P> - -</P> -<DT>Referenced variables of a subtemplate -<DD>The referenced variables of a subtemplate are the pattern variables that -appear within it. -<P> - -</P> -<DT>Variables opened by an ellipsis template -<DD>The variables opened by an ellipsis template are the referenced pattern -variables whose rank is greater than the rank of the ellipsis template. -<P> - -</DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC29"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC28"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC30"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.4.2 Restrictions </H3> -<!--docid::SEC29::--> -<P> - -No pattern variable appears more than once within a pattern. -</P> -<P> - -For every occurrence of a pattern variable within a template, the -template rank of the occurrence must be greater than or equal to the -pattern variable's rank. -</P> -<P> - -Every ellipsis template must open at least one variable. -</P> -<P> - -For every ellipsis template, the variables opened by an ellipsis -template must all be bound to sequences of the same length. -</P> -<P> - -The compiled form of a <VAR>rule</VAR> is -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>rule ==> (pattern template inserted) - -pattern ==> pattern_var - | symbol - | () - | (pattern . pattern) - | ellipsis_pattern - | #(pattern) - | pattern_datum - -template ==> pattern_var - | symbol - | () - | (template2 . template2) - | #(pattern) - | pattern_datum - -template2 ==> template - | ellipsis_template - -pattern_datum ==> string - | character - | boolean - | number - -pattern_var ==> #(V symbol rank) - -ellipsis_pattern ==> #(E pattern pattern_vars) - -ellipsis_template ==> #(E template pattern_vars) - -inserted ==> () - | (symbol . inserted) - -pattern_vars ==> () - | (pattern_var . pattern_vars) - -rank ==> exact non-negative integer -</pre></td></tr></table><P> - -where V and E are unforgeable values. -</P> -<P> - -The pattern variables associated with an ellipsis pattern are the -variables bound by the pattern, and the pattern variables associated -with an ellipsis template are the variables opened by the ellipsis -template. -</P> -<P> - -If the template contains a big chunk that contains no pattern variables -or inserted identifiers, then the big chunk will be copied -unnecessarily. That shouldn't matter very often. -</P> -<P> - -<A NAME="Syntactic Closures"></A> -<HR SIZE="6"> -<A NAME="SEC30"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC29"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC31"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.5 Syntactic Closures </H2> -<!--docid::SEC30::--> -<P> - -<CODE>(require 'syntactic-closures)</CODE> -<A NAME="IDX130"></A> -</P> -<P> - -<A NAME="IDX131"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:expand</B> <I>expression</I> -<DD><A NAME="IDX132"></A> -<DT><U>Function:</U> <B>synclo:expand</B> <I>expression</I> -<DD>Returns scheme code with the macros and derived expression types of -<VAR>expression</VAR> expanded to primitive expression types. -</DL> -<P> - -<A NAME="IDX133"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:eval</B> <I>expression</I> -<DD><A NAME="IDX134"></A> -<DT><U>Function:</U> <B>synclo:eval</B> <I>expression</I> -<DD><CODE>macro:eval</CODE> returns the value of <VAR>expression</VAR> in the current -top level environment. <VAR>expression</VAR> can contain macro definitions. -Side effects of <VAR>expression</VAR> will affect the top level -environment. -</DL> -<P> - -<A NAME="IDX135"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>macro:load</B> <I>filename</I> -<DD><A NAME="IDX136"></A> -<DT><U>Procedure:</U> <B>synclo:load</B> <I>filename</I> -<DD><VAR>filename</VAR> should be a string. If filename names an existing file, -the <CODE>macro:load</CODE> procedure reads Scheme source code expressions and -definitions from the file and evaluates them sequentially. These -source code expressions and definitions may contain macro definitions. -The <CODE>macro:load</CODE> procedure does not affect the values returned by -<CODE>current-input-port</CODE> and <CODE>current-output-port</CODE>. -</DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC31"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC30"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC32"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.5.1 Syntactic Closure Macro Facility </H3> -<!--docid::SEC31::--> -<P> - -<center> - A Syntactic Closures Macro Facility -</center> -<center> - by Chris Hanson -</center> -<center> - 9 November 1991 -</center> -</P> -<P> - -This document describes <EM>syntactic closures</EM>, a low-level macro -facility for the Scheme programming language. The facility is an -alternative to the low-level macro facility described in the -<CITE>Revised^4 Report on Scheme.</CITE> This document is an addendum to that -report. -</P> -<P> - -The syntactic closures facility extends the BNF rule for -<VAR>transformer spec</VAR> to allow a new keyword that introduces a -low-level macro transformer: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre><VAR>transformer spec</VAR> := (transformer <VAR>expression</VAR>) -</pre></td></tr></table><P> - -Additionally, the following procedures are added: -<TABLE><tr><td> </td><td class=example><pre>make-syntactic-closure -capture-syntactic-environment -identifier? -identifier=? -</pre></td></tr></table><P> - -The description of the facility is divided into three parts. The first -part defines basic terminology. The second part describes how macro -transformers are defined. The third part describes the use of -<EM>identifiers</EM>, which extend the syntactic closure mechanism to be -compatible with <CODE>syntax-rules</CODE>. -</P> -<P> - -<HR SIZE="6"> -<A NAME="SEC32"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC31"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC33"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 3.5.1.1 Terminology </H4> -<!--docid::SEC32::--> -<P> - -This section defines the concepts and data types used by the syntactic -closures facility. -</P> -<P> - -<UL> - -<LI><EM>Forms</EM> are the syntactic entities out of which programs are -recursively constructed. A form is any expression, any definition, any -syntactic keyword, or any syntactic closure. The variable name that -appears in a <CODE>set!</CODE> special form is also a form. Examples of -forms: -<P> - -<TABLE><tr><td> </td><td class=example><pre>17 -#t -car -(+ x 4) -(lambda (x) x) -(define pi 3.14159) -if -define -</pre></td></tr></table><P> - -</P> -<LI>An <EM>alias</EM> is an alternate name for a given symbol. It can -appear anywhere in a form that the symbol could be used, and when quoted -it is replaced by the symbol; however, it does not satisfy the predicate -<CODE>symbol?</CODE>. Macro transformers rarely distinguish symbols from -aliases, referring to both as identifiers. -<P> - -</P> -<LI>A <EM>syntactic</EM> environment maps identifiers to their -meanings. More precisely, it determines whether an identifier is a -syntactic keyword or a variable. If it is a keyword, the meaning is an -interpretation for the form in which that keyword appears. If it is a -variable, the meaning identifies which binding of that variable is -referenced. In short, syntactic environments contain all of the -contextual information necessary for interpreting the meaning of a -particular form. -<P> - -</P> -<LI>A <EM>syntactic closure</EM> consists of a form, a syntactic -environment, and a list of identifiers. All identifiers in the form -take their meaning from the syntactic environment, except those in the -given list. The identifiers in the list are to have their meanings -determined later. A syntactic closure may be used in any context in -which its form could have been used. Since a syntactic closure is also -a form, it may not be used in contexts where a form would be illegal. -For example, a form may not appear as a clause in the cond special form. -A syntactic closure appearing in a quoted structure is replaced by its -form. -<P> - -</UL> -<P> - -<HR SIZE="6"> -<A NAME="SEC33"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC32"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC34"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 3.5.1.2 Transformer Definition </H4> -<!--docid::SEC33::--> -<P> - -This section describes the <CODE>transformer</CODE> special form and the -procedures <CODE>make-syntactic-closure</CODE> and -<CODE>capture-syntactic-environment</CODE>. -</P> -<P> - -<A NAME="IDX137"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>transformer</B> <I>expression</I> -<DD><P> - -Syntax: It is an error if this syntax occurs except as a -<VAR>transformer spec</VAR>. -</P> -<P> - -Semantics: The <VAR>expression</VAR> is evaluated in the standard transformer -environment to yield a macro transformer as described below. This macro -transformer is bound to a macro keyword by the special form in which the -<CODE>transformer</CODE> expression appears (for example, -<CODE>let-syntax</CODE>). -</P> -<P> - -A <EM>macro transformer</EM> is a procedure that takes two arguments, a -form and a syntactic environment, and returns a new form. The first -argument, the <EM>input form</EM>, is the form in which the macro keyword -occurred. The second argument, the <EM>usage environment</EM>, is the -syntactic environment in which the input form occurred. The result of -the transformer, the <EM>output form</EM>, is automatically closed in the -<EM>transformer environment</EM>, which is the syntactic environment in -which the <CODE>transformer</CODE> expression occurred. -</P> -<P> - -For example, here is a definition of a push macro using -<CODE>syntax-rules</CODE>: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-syntax push - (syntax-rules () - ((push item list) - (set! list (cons item list))))) -</pre></td></tr></table><P> - -Here is an equivalent definition using <CODE>transformer</CODE>: -<TABLE><tr><td> </td><td class=example><pre>(define-syntax push - (transformer - (lambda (exp env) - (let ((item - (make-syntactic-closure env '() (cadr exp))) - (list - (make-syntactic-closure env '() (caddr exp)))) - `(set! ,list (cons ,item ,list)))))) -</pre></td></tr></table><P> - -In this example, the identifiers <CODE>set!</CODE> and <CODE>cons</CODE> are closed -in the transformer environment, and thus will not be affected by the -meanings of those identifiers in the usage environment -<CODE>env</CODE>. -</P> -<P> - -Some macros may be non-hygienic by design. For example, the following -defines a loop macro that implicitly binds <CODE>exit</CODE> to an escape -procedure. The binding of <CODE>exit</CODE> is intended to capture free -references to <CODE>exit</CODE> in the body of the loop, so <CODE>exit</CODE> must -be left free when the body is closed: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-syntax loop - (transformer - (lambda (exp env) - (let ((body (cdr exp))) - `(call-with-current-continuation - (lambda (exit) - (let f () - ,@(map (lambda (exp) - (make-syntactic-closure env '(exit) - exp)) - body) - (f)))))))) -</pre></td></tr></table><P> - -To assign meanings to the identifiers in a form, use -<CODE>make-syntactic-closure</CODE> to close the form in a syntactic -environment. -</P> -</DL> -<P> - -<A NAME="IDX138"></A> -</P> -<DL> -<DT><U>Function:</U> <B>make-syntactic-closure</B> <I>environment free-names form</I> -<DD><P> - -<VAR>environment</VAR> must be a syntactic environment, <VAR>free-names</VAR> must -be a list of identifiers, and <VAR>form</VAR> must be a form. -<CODE>make-syntactic-closure</CODE> constructs and returns a syntactic closure -of <VAR>form</VAR> in <VAR>environment</VAR>, which can be used anywhere that -<VAR>form</VAR> could have been used. All the identifiers used in -<VAR>form</VAR>, except those explicitly excepted by <VAR>free-names</VAR>, obtain -their meanings from <VAR>environment</VAR>. -</P> -<P> - -Here is an example where <VAR>free-names</VAR> is something other than the -empty list. It is instructive to compare the use of <VAR>free-names</VAR> in -this example with its use in the <CODE>loop</CODE> example above: the examples -are similar except for the source of the identifier being left -free. -<TABLE><tr><td> </td><td class=example><pre>(define-syntax let1 - (transformer - (lambda (exp env) - (let ((id (cadr exp)) - (init (caddr exp)) - (exp (cadddr exp))) - `((lambda (,id) - ,(make-syntactic-closure env (list id) exp)) - ,(make-syntactic-closure env '() init)))))) -</pre></td></tr></table><P> - -<CODE>let1</CODE> is a simplified version of <CODE>let</CODE> that only binds a -single identifier, and whose body consists of a single expression. When -the body expression is syntactically closed in its original syntactic -environment, the identifier that is to be bound by <CODE>let1</CODE> must be -left free, so that it can be properly captured by the <CODE>lambda</CODE> in -the output form. -</P> -<P> - -To obtain a syntactic environment other than the usage environment, use -<CODE>capture-syntactic-environment</CODE>. -</P> -</DL> -<P> - -<A NAME="IDX139"></A> -</P> -<DL> -<DT><U>Function:</U> <B>capture-syntactic-environment</B> <I>procedure</I> -<DD><P> - -<CODE>capture-syntactic-environment</CODE> returns a form that will, when -transformed, call <VAR>procedure</VAR> on the current syntactic environment. -<VAR>procedure</VAR> should compute and return a new form to be transformed, -in that same syntactic environment, in place of the form. -</P> -<P> - -An example will make this clear. Suppose we wanted to define a simple -<CODE>loop-until</CODE> keyword equivalent to -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-syntax loop-until - (syntax-rules () - ((loop-until id init test return step) - (letrec ((loop - (lambda (id) - (if test return (loop step))))) - (loop init))))) -</pre></td></tr></table><P> - -The following attempt at defining <CODE>loop-until</CODE> has a subtle bug: -<TABLE><tr><td> </td><td class=example><pre>(define-syntax loop-until - (transformer - (lambda (exp env) - (let ((id (cadr exp)) - (init (caddr exp)) - (test (cadddr exp)) - (return (cadddr (cdr exp))) - (step (cadddr (cddr exp))) - (close - (lambda (exp free) - (make-syntactic-closure env free exp)))) - `(letrec ((loop - (lambda (,id) - (if ,(close test (list id)) - ,(close return (list id)) - (loop ,(close step (list id))))))) - (loop ,(close init '()))))))) -</pre></td></tr></table><P> - -This definition appears to take all of the proper precautions to prevent -unintended captures. It carefully closes the subexpressions in their -original syntactic environment and it leaves the <CODE>id</CODE> identifier -free in the <CODE>test</CODE>, <CODE>return</CODE>, and <CODE>step</CODE> expressions, so -that it will be captured by the binding introduced by the <CODE>lambda</CODE> -expression. Unfortunately it uses the identifiers <CODE>if</CODE> and -<CODE>loop</CODE> within that <CODE>lambda</CODE> expression, so if the user of -<CODE>loop-until</CODE> just happens to use, say, <CODE>if</CODE> for the -identifier, it will be inadvertently captured. -</P> -<P> - -The syntactic environment that <CODE>if</CODE> and <CODE>loop</CODE> want to be -exposed to is the one just outside the <CODE>lambda</CODE> expression: before -the user's identifier is added to the syntactic environment, but after -the identifier loop has been added. -<CODE>capture-syntactic-environment</CODE> captures exactly that environment -as follows: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(define-syntax loop-until - (transformer - (lambda (exp env) - (let ((id (cadr exp)) - (init (caddr exp)) - (test (cadddr exp)) - (return (cadddr (cdr exp))) - (step (cadddr (cddr exp))) - (close - (lambda (exp free) - (make-syntactic-closure env free exp)))) - `(letrec ((loop - ,(capture-syntactic-environment - (lambda (env) - `(lambda (,id) - (,(make-syntactic-closure env '() `if) - ,(close test (list id)) - ,(close return (list id)) - (,(make-syntactic-closure env '() - `loop) - ,(close step (list id))))))))) - (loop ,(close init '()))))))) -</pre></td></tr></table><P> - -In this case, having captured the desired syntactic environment, it is -convenient to construct syntactic closures of the identifiers <CODE>if</CODE> -and the <CODE>loop</CODE> and use them in the body of the -<CODE>lambda</CODE>. -</P> -<P> - -A common use of <CODE>capture-syntactic-environment</CODE> is to get the -transformer environment of a macro transformer: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(transformer - (lambda (exp env) - (capture-syntactic-environment - (lambda (transformer-env) - ...)))) -</pre></td></tr></table></DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC34"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC33"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC35"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 3.5.1.3 Identifiers </H4> -<!--docid::SEC34::--> -<P> - -This section describes the procedures that create and manipulate -identifiers. Previous syntactic closure proposals did not have an -identifier data type -- they just used symbols. The identifier data -type extends the syntactic closures facility to be compatible with the -high-level <CODE>syntax-rules</CODE> facility. -</P> -<P> - -As discussed earlier, an identifier is either a symbol or an -<EM>alias</EM>. An alias is implemented as a syntactic closure whose -<EM>form</EM> is an identifier: -</P> -<P> - -<TABLE><tr><td> </td><td class=example><pre>(make-syntactic-closure env '() 'a) - => an <EM>alias</EM> -</pre></td></tr></table><P> - -Aliases are implemented as syntactic closures because they behave just -like syntactic closures most of the time. The difference is that an -alias may be bound to a new value (for example by <CODE>lambda</CODE> or -<CODE>let-syntax</CODE>); other syntactic closures may not be used this way. -If an alias is bound, then within the scope of that binding it is looked -up in the syntactic environment just like any other identifier. -</P> -<P> - -Aliases are used in the implementation of the high-level facility -<CODE>syntax-rules</CODE>. A macro transformer created by <CODE>syntax-rules</CODE> -uses a template to generate its output form, substituting subforms of -the input form into the template. In a syntactic closures -implementation, all of the symbols in the template are replaced by -aliases closed in the transformer environment, while the output form -itself is closed in the usage environment. This guarantees that the -macro transformation is hygienic, without requiring the transformer to -know the syntactic roles of the substituted input subforms. -</P> -<P> - -<A NAME="IDX140"></A> -</P> -<DL> -<DT><U>Function:</U> <B>identifier?</B> <I>object</I> -<DD>Returns <CODE>#t</CODE> if <VAR>object</VAR> is an identifier, otherwise returns -<CODE>#f</CODE>. Examples: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(identifier? 'a) - => #t -(identifier? (make-syntactic-closure env '() 'a)) - => #t -(identifier? "a") - => #f -(identifier? #\a) - => #f -(identifier? 97) - => #f -(identifier? #f) - => #f -(identifier? '(a)) - => #f -(identifier? '#(a)) - => #f -</pre></td></tr></table><P> - -The predicate <CODE>eq?</CODE> is used to determine if two identifers are -"the same". Thus <CODE>eq?</CODE> can be used to compare identifiers -exactly as it would be used to compare symbols. Often, though, it is -useful to know whether two identifiers "mean the same thing". For -example, the <CODE>cond</CODE> macro uses the symbol <CODE>else</CODE> to identify -the final clause in the conditional. A macro transformer for -<CODE>cond</CODE> cannot just look for the symbol <CODE>else</CODE>, because the -<CODE>cond</CODE> form might be the output of another macro transformer that -replaced the symbol <CODE>else</CODE> with an alias. Instead the transformer -must look for an identifier that "means the same thing" in the usage -environment as the symbol <CODE>else</CODE> means in the transformer -environment. -</P> -</DL> -<P> - -<A NAME="IDX141"></A> -</P> -<DL> -<DT><U>Function:</U> <B>identifier=?</B> <I>environment1 identifier1 environment2 identifier2</I> -<DD><VAR>environment1</VAR> and <VAR>environment2</VAR> must be syntactic -environments, and <VAR>identifier1</VAR> and <VAR>identifier2</VAR> must be -identifiers. <CODE>identifier=?</CODE> returns <CODE>#t</CODE> if the meaning of -<VAR>identifier1</VAR> in <VAR>environment1</VAR> is the same as that of -<VAR>identifier2</VAR> in <VAR>environment2</VAR>, otherwise it returns <CODE>#f</CODE>. -Examples: -<P> - -<TABLE><tr><td> </td><td class=example><pre>(let-syntax - ((foo - (transformer - (lambda (form env) - (capture-syntactic-environment - (lambda (transformer-env) - (identifier=? transformer-env 'x env 'x))))))) - (list (foo) - (let ((x 3)) - (foo)))) - => (#t #f) -</pre></td></tr></table><P> - -<TABLE><tr><td> </td><td class=example><pre>(let-syntax ((bar foo)) - (let-syntax - ((foo - (transformer - (lambda (form env) - (capture-syntactic-environment - (lambda (transformer-env) - (identifier=? transformer-env 'foo - env (cadr form)))))))) - (list (foo foo) - (foobar)))) - => (#f #t) -</pre></td></tr></table></DL> -<P> - -<HR SIZE="6"> -<A NAME="SEC35"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC34"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC36"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H4> 3.5.1.4 Acknowledgements </H4> -<!--docid::SEC35::--> -<P> - -The syntactic closures facility was invented by Alan Bawden and Jonathan -Rees. The use of aliases to implement <CODE>syntax-rules</CODE> was invented -by Alan Bawden (who prefers to call them <EM>synthetic names</EM>). Much -of this proposal is derived from an earlier proposal by Alan -Bawden. -</P> -<P> - -<A NAME="Syntax-Case Macros"></A> -<HR SIZE="6"> -<A NAME="SEC36"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC35"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC37"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.6 Syntax-Case Macros </H2> -<!--docid::SEC36::--> -<P> - -<CODE>(require 'syntax-case)</CODE> -<A NAME="IDX142"></A> -</P> -<P> - -<A NAME="IDX143"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:expand</B> <I>expression</I> -<DD><A NAME="IDX144"></A> -<DT><U>Function:</U> <B>syncase:expand</B> <I>expression</I> -<DD>Returns scheme code with the macros and derived expression types of -<VAR>expression</VAR> expanded to primitive expression types. -</DL> -<P> - -<A NAME="IDX145"></A> -</P> -<DL> -<DT><U>Function:</U> <B>macro:eval</B> <I>expression</I> -<DD><A NAME="IDX146"></A> -<DT><U>Function:</U> <B>syncase:eval</B> <I>expression</I> -<DD><CODE>macro:eval</CODE> returns the value of <VAR>expression</VAR> in the current -top level environment. <VAR>expression</VAR> can contain macro definitions. -Side effects of <VAR>expression</VAR> will affect the top level -environment. -</DL> -<P> - -<A NAME="IDX147"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>macro:load</B> <I>filename</I> -<DD><A NAME="IDX148"></A> -<DT><U>Procedure:</U> <B>syncase:load</B> <I>filename</I> -<DD><VAR>filename</VAR> should be a string. If filename names an existing file, -the <CODE>macro:load</CODE> procedure reads Scheme source code expressions and -definitions from the file and evaluates them sequentially. These -source code expressions and definitions may contain macro definitions. -The <CODE>macro:load</CODE> procedure does not affect the values returned by -<CODE>current-input-port</CODE> and <CODE>current-output-port</CODE>. -</DL> -<P> - -This is version 2.1 of <CODE>syntax-case</CODE>, the low-level macro facility -proposed and implemented by Robert Hieb and R. Kent Dybvig. -</P> -<P> - -This version is further adapted by Harald Hanche-Olsen -<hanche @ imf.unit.no> to make it compatible with, and easily usable -with, SLIB. Mainly, these adaptations consisted of: -</P> -<P> - -<UL> -<LI> -Removing white space from `<TT>expand.pp</TT>' to save space in the -distribution. This file is not meant for human readers anyway<small>...</small> -<P> - -</P> -<LI> -Removed a couple of Chez scheme dependencies. -<P> - -</P> -<LI> -Renamed global variables used to minimize the possibility of name -conflicts. -<P> - -</P> -<LI> -Adding an SLIB-specific initialization file. -<P> - -</P> -<LI> -Removing a couple extra files, most notably the documentation (but see -below). -</UL> -<P> - -If you wish, you can see exactly what changes were done by reading the -shell script in the file `<TT>syncase.sh</TT>'. -</P> -<P> - -The two PostScript files were omitted in order to not burden the SLIB -distribution with them. If you do intend to use <CODE>syntax-case</CODE>, -however, you should get these files and print them out on a PostScript -printer. They are available with the original <CODE>syntax-case</CODE> -distribution by anonymous FTP in -`<TT>cs.indiana.edu:/pub/scheme/syntax-case</TT>'. -</P> -<P> - -In order to use syntax-case from an interactive top level, execute: -<TABLE><tr><td> </td><td class=example><pre>(require 'syntax-case) -<A NAME="IDX149"></A>(require 'repl) -<A NAME="IDX150"></A>(repl:top-level macro:eval) -</pre></td></tr></table>See the section Repl (see section <A HREF="slib_7.html#SEC264">7.5.1 Repl</A>) for more information. -<P> - -To check operation of syntax-case get -`<TT>cs.indiana.edu:/pub/scheme/syntax-case</TT>', and type -<TABLE><tr><td> </td><td class=example><pre>(require 'syntax-case) -<A NAME="IDX151"></A><A NAME="IDX152"></A>(syncase:sanity-check) -</pre></td></tr></table><P> - -Beware that <CODE>syntax-case</CODE> takes a long time to load -- about 20s on -a SPARCstation SLC (with SCM) and about 90s on a Macintosh SE/30 (with -Gambit). -</P> -<P> - -<HR SIZE="6"> -<A NAME="SEC37"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC36"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC38"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.6.1 Notes </H3> -<!--docid::SEC37::--> -<P> - -All R4RS syntactic forms are defined, including <CODE>delay</CODE>. Along -with <CODE>delay</CODE> are simple definitions for <CODE>make-promise</CODE> (into -which <CODE>delay</CODE> expressions expand) and <CODE>force</CODE>. -</P> -<P> - -<CODE>syntax-rules</CODE> and <CODE>with-syntax</CODE> (described in <CITE>TR356</CITE>) -are defined. -</P> -<P> - -<CODE>syntax-case</CODE> is actually defined as a macro that expands into -calls to the procedure <CODE>syntax-dispatch</CODE> and the core form -<CODE>syntax-lambda</CODE>; do not redefine these names. -</P> -<P> - -Several other top-level bindings not documented in TR356 are created: -<UL> -<LI>the "hooks" in `<TT>hooks.ss</TT>' -<LI>the <CODE>build-</CODE> procedures in `<TT>output.ss</TT>' -<LI><CODE>expand-syntax</CODE> (the expander) -</UL> -<P> - -The syntax of define has been extended to allow <CODE>(define <VAR>id</VAR>)</CODE>, -which assigns <VAR>id</VAR> to some unspecified value. -</P> -<P> - -We have attempted to maintain R4RS compatibility where possible. The -incompatibilities should be confined to `<TT>hooks.ss</TT>'. Please let us -know if there is some incompatibility that is not flagged as such. -</P> -<P> - -Send bug reports, comments, suggestions, and questions to Kent Dybvig -(dyb @ iuvax.cs.indiana.edu). -</P> -<P> - -<HR SIZE="6"> -<A NAME="SEC38"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC37"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC39"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.6.2 Note from SLIB maintainer </H3> -<!--docid::SEC38::--> -<P> - -<CODE>(require 'structure)</CODE> -</P> -<P> - -<A NAME="IDX153"></A> -Included with the <CODE>syntax-case</CODE> files was `<TT>structure.scm</TT>' -which defines a macro <CODE>define-structure</CODE>. I have no -documentation for this macro; it is not used by any other code in -SLIB. -</P> -<P> - -<A NAME="Fluid-Let"></A> -<HR SIZE="6"> -<A NAME="SEC39"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC38"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.7 Fluid-Let </H2> -<!--docid::SEC39::--> -<P> - -<CODE>(require 'fluid-let)</CODE> -<A NAME="IDX154"></A> -</P> -<P> - -<A NAME="IDX155"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>fluid-let</B> <I><CODE>(<VAR>bindings</VAR> <small>...</small>)</CODE> <VAR>forms</VAR><small>...</small></I> -<DD></DL> -<TABLE><tr><td> </td><td class=example><pre>(fluid-let ((<VAR>variable</VAR> <VAR>init</VAR>) <small>...</small>) - <VAR>expression</VAR> <VAR>expression</VAR> <small>...</small>) -</pre></td></tr></table><P> - -The <VAR>init</VAR>s are evaluated in the current environment (in some -unspecified order), the current values of the <VAR>variable</VAR>s are saved, -the results are assigned to the <VAR>variable</VAR>s, the <VAR>expression</VAR>s -are evaluated sequentially in the current environment, the -<VAR>variable</VAR>s are restored to their original values, and the value of -the last <VAR>expression</VAR> is returned. -</P> -<P> - -The syntax of this special form is similar to that of <CODE>let</CODE>, but -<CODE>fluid-let</CODE> temporarily rebinds existing <VAR>variable</VAR>s. Unlike -<CODE>let</CODE>, <CODE>fluid-let</CODE> creates no new bindings; instead it -<EM>assigns</EM> the values of each <VAR>init</VAR> to the binding (determined -by the rules of lexical scoping) of its corresponding -<VAR>variable</VAR>. -</P> -<P> - -<A NAME="Yasos"></A> -<HR SIZE="6"> -<A NAME="SEC40"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC39"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC41"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H2> 3.8 Yasos </H2> -<!--docid::SEC40::--> -<P> - -<CODE>(require 'oop)</CODE> or <CODE>(require 'yasos)</CODE> -<A NAME="IDX156"></A> -<A NAME="IDX157"></A> -</P> -<P> - -`Yet Another Scheme Object System' is a simple object system for Scheme -based on the paper by Norman Adams and Jonathan Rees: <CITE>Object -Oriented Programming in Scheme</CITE>, Proceedings of the 1988 ACM Conference -on LISP and Functional Programming, July 1988 [ACM #552880]. -</P> -<P> - -Another reference is: -</P> -<P> - -Ken Dickey. -<A HREF="ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/pubs/swob.txt"> -Scheming with Objects -</A> -<CITE>AI Expert</CITE> Volume 7, Number 10 (October 1992), pp. 24-33. -</P> -<P> - -<TABLE BORDER="0" CELLSPACING="0"> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC41">3.8.1 Terms</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Definitions and disclaimer.</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC42">3.8.2 Interface</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">The Yasos macros and procedures.</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC43">3.8.3 Setters</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Dylan-like setters in Yasos.</TD></TR> -<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_3.html#SEC44">3.8.4 Examples</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Usage of Yasos and setters.</TD></TR> -</TABLE> -<P> - -<A NAME="Yasos terms"></A> -<HR SIZE="6"> -<A NAME="SEC41"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC42"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.8.1 Terms </H3> -<!--docid::SEC41::--> -<P> - -</P> -<DL COMPACT> -<DT><EM>Object</EM> -<DD>Any Scheme data object. -<P> - -</P> -<DT><EM>Instance</EM> -<DD>An instance of the OO system; an <EM>object</EM>. -<P> - -</P> -<DT><EM>Operation</EM> -<DD>A <VAR>method</VAR>. -</DL> -<P> - -</P> -<DL COMPACT> -<DT><EM>Notes:</EM> -<DD>The object system supports multiple inheritance. An instance can -inherit from 0 or more ancestors. In the case of multiple inherited -operations with the same identity, the operation used is that from the -first ancestor which contains it (in the ancestor <CODE>let</CODE>). An -operation may be applied to any Scheme data object--not just instances. -As code which creates instances is just code, there are no <EM>classes</EM> -and no meta-<VAR>anything</VAR>. Method dispatch is by a procedure call a la -CLOS rather than by <CODE>send</CODE> syntax a la Smalltalk. -<P> - -</P> -<DT><EM>Disclaimer:</EM> -<DD>There are a number of optimizations which can be made. This -implementation is expository (although performance should be quite -reasonable). See the L&FP paper for some suggestions. -</DL> -<P> - -<A NAME="Yasos interface"></A> -<HR SIZE="6"> -<A NAME="SEC42"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC41"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC43"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.8.2 Interface </H3> -<!--docid::SEC42::--> -<P> - -<A NAME="IDX158"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>define-operation</B> <I><CODE>(</CODE>opname self arg <small>...</small><CODE>)</CODE> <VAR>default-body</VAR></I> -<DD>Defines a default behavior for data objects which don't handle the -operation <VAR>opname</VAR>. The default behavior (for an empty -<VAR>default-body</VAR>) is to generate an error. -</DL> -<P> - -<A NAME="IDX159"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>define-predicate</B> <I>opname?</I> -<DD>Defines a predicate <VAR>opname?</VAR>, usually used for determining the -<EM>type</EM> of an object, such that <CODE>(<VAR>opname?</VAR> <VAR>object</VAR>)</CODE> -returns <CODE>#t</CODE> if <VAR>object</VAR> has an operation <VAR>opname?</VAR> and -<CODE>#f</CODE> otherwise. -</DL> -<P> - -<A NAME="IDX160"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>object</B> <I><CODE>((<VAR>name</VAR> <VAR>self</VAR> <VAR>arg</VAR> <small>...</small>) <VAR>body</VAR>)</CODE> <small>...</small></I> -<DD>Returns an object (an instance of the object system) with operations. -Invoking <CODE>(<VAR>name</VAR> <VAR>object</VAR> <VAR>arg</VAR> <small>...</small></CODE> executes the -<VAR>body</VAR> of the <VAR>object</VAR> with <VAR>self</VAR> bound to <VAR>object</VAR> and -with argument(s) <VAR>arg</VAR><small>...</small>. -</DL> -<P> - -<A NAME="IDX161"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>object-with-ancestors</B> <I><CODE>((</CODE>ancestor1 init1<CODE>)</CODE> <small>...</small><CODE>)</CODE> operation <small>...</small></I> -<DD>A <CODE>let</CODE>-like form of <CODE>object</CODE> for multiple inheritance. It -returns an object inheriting the behaviour of <VAR>ancestor1</VAR> etc. An -operation will be invoked in an ancestor if the object itself does not -provide such a method. In the case of multiple inherited operations -with the same identity, the operation used is the one found in the first -ancestor in the ancestor list. -</DL> -<P> - -<A NAME="IDX162"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>operate-as</B> <I>component operation self arg <small>...</small></I> -<DD>Used in an operation definition (of <VAR>self</VAR>) to invoke the -<VAR>operation</VAR> in an ancestor <VAR>component</VAR> but maintain the object's -identity. Also known as "send-to-super". -</DL> -<P> - -<A NAME="IDX163"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>print</B> <I>obj port</I> -<DD>A default <CODE>print</CODE> operation is provided which is just <CODE>(format -<VAR>port</VAR> <VAR>obj</VAR>)</CODE> (see section <A HREF="slib_4.html#SEC53">4.2 Format (version 3.0)</A>) for non-instances and prints -<VAR>obj</VAR> preceded by `<SAMP>#<INSTANCE></SAMP>' for instances. -</DL> -<P> - -<A NAME="IDX164"></A> -</P> -<DL> -<DT><U>Function:</U> <B>size</B> <I>obj</I> -<DD>The default method returns the number of elements in <VAR>obj</VAR> if it is -a vector, string or list, <CODE>2</CODE> for a pair, <CODE>1</CODE> for a character -and by default id an error otherwise. Objects such as collections -(see section <A HREF="slib_7.html#SEC194">7.1.9 Collections</A>) may override the default in an obvious way. -</DL> -<P> - -<A NAME="Setters"></A> -<HR SIZE="6"> -<A NAME="SEC43"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC42"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC44"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.8.3 Setters </H3> -<!--docid::SEC43::--> -<P> - -<EM>Setters</EM> implement <EM>generalized locations</EM> for objects -associated with some sort of mutable state. A <EM>getter</EM> operation -retrieves a value from a generalized location and the corresponding -setter operation stores a value into the location. Only the getter is -named -- the setter is specified by a procedure call as below. (Dylan -uses special syntax.) Typically, but not necessarily, getters are -access operations to extract values from Yasos objects (see section <A HREF="slib_3.html#SEC40">3.8 Yasos</A>). -Several setters are predefined, corresponding to getters <CODE>car</CODE>, -<CODE>cdr</CODE>, <CODE>string-ref</CODE> and <CODE>vector-ref</CODE> e.g., <CODE>(setter -car)</CODE> is equivalent to <CODE>set-car!</CODE>. -</P> -<P> - -This implementation of setters is similar to that in Dylan(TM) -(<CITE>Dylan: An object-oriented dynamic language</CITE>, Apple Computer -Eastern Research and Technology). Common LISP provides similar -facilities through <CODE>setf</CODE>. -</P> -<P> - -<A NAME="IDX165"></A> -</P> -<DL> -<DT><U>Function:</U> <B>setter</B> <I>getter</I> -<DD>Returns the setter for the procedure <VAR>getter</VAR>. E.g., since -<CODE>string-ref</CODE> is the getter corresponding to a setter which is -actually <CODE>string-set!</CODE>: -<TABLE><tr><td> </td><td class=example><pre>(define foo "foo") -((setter string-ref) foo 0 #\F) ; set element 0 of foo -foo => "Foo" -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX166"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>set</B> <I>place new-value</I> -<DD>If <VAR>place</VAR> is a variable name, <CODE>set</CODE> is equivalent to -<CODE>set!</CODE>. Otherwise, <VAR>place</VAR> must have the form of a procedure -call, where the procedure name refers to a getter and the call indicates -an accessible generalized location, i.e., the call would return a value. -The return value of <CODE>set</CODE> is usually unspecified unless used with a -setter whose definition guarantees to return a useful value. -<TABLE><tr><td> </td><td class=example><pre>(set (string-ref foo 2) #\O) ; generalized location with getter -foo => "FoO" -(set foo "foo") ; like set! -foo => "foo" -</pre></td></tr></table></DL> -<P> - -<A NAME="IDX167"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>add-setter</B> <I>getter setter</I> -<DD>Add procedures <VAR>getter</VAR> and <VAR>setter</VAR> to the (inaccessible) list -of valid setter/getter pairs. <VAR>setter</VAR> implements the store -operation corresponding to the <VAR>getter</VAR> access operation for the -relevant state. The return value is unspecified. -</DL> -<P> - -<A NAME="IDX168"></A> -</P> -<DL> -<DT><U>Procedure:</U> <B>remove-setter-for</B> <I>getter</I> -<DD>Removes the setter corresponding to the specified <VAR>getter</VAR> from the -list of valid setters. The return value is unspecified. -</DL> -<P> - -<A NAME="IDX169"></A> -</P> -<DL> -<DT><U>Syntax:</U> <B>define-access-operation</B> <I>getter-name</I> -<DD>Shorthand for a Yasos <CODE>define-operation</CODE> defining an operation -<VAR>getter-name</VAR> that objects may support to return the value of some -mutable state. The default operation is to signal an error. The return -value is unspecified. -</DL> -<P> - -<A NAME="Yasos examples"></A> -<HR SIZE="6"> -<A NAME="SEC44"></A> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC43"> < </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> > </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC40"> Up </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<H3> 3.8.4 Examples </H3> -<!--docid::SEC44::--> -<P> - -<TABLE><tr><td> </td><td class=example><pre>;;; These definitions for PRINT and SIZE are -;;; already supplied by -(require 'yasos) - -(define-operation (print obj port) - (format port - (if (instance? obj) "#<instance>" "~s") - obj)) - -(define-operation (size obj) - (cond - ((vector? obj) (vector-length obj)) - ((list? obj) (length obj)) - ((pair? obj) 2) - ((string? obj) (string-length obj)) - ((char? obj) 1) - (else - (slib:error "Operation not supported: size" obj)))) - -(define-predicate cell?) -(define-operation (fetch obj)) -(define-operation (store! obj newValue)) - -(define (make-cell value) - (object - ((cell? self) #t) - ((fetch self) value) - ((store! self newValue) - (set! value newValue) - newValue) - ((size self) 1) - ((print self port) - (format port "#<Cell: ~s>" (fetch self))))) - -(define-operation (discard obj value) - (format #t "Discarding ~s~%" value)) - -(define (make-filtered-cell value filter) - (object-with-ancestors - ((cell (make-cell value))) - ((store! self newValue) - (if (filter newValue) - (store! cell newValue) - (discard self newValue))))) - -(define-predicate array?) -(define-operation (array-ref array index)) -(define-operation (array-set! array index value)) - -(define (make-array num-slots) - (let ((anArray (make-vector num-slots))) - (object - ((array? self) #t) - ((size self) num-slots) - ((array-ref self index) - (vector-ref anArray index)) - ((array-set! self index newValue) - (vector-set! anArray index newValue)) - ((print self port) - (format port "#<Array ~s>" (size self)))))) - -(define-operation (position obj)) -(define-operation (discarded-value obj)) - -(define (make-cell-with-history value filter size) - (let ((pos 0) (most-recent-discard #f)) - (object-with-ancestors - ((cell (make-filtered-call value filter)) - (sequence (make-array size))) - ((array? self) #f) - ((position self) pos) - ((store! self newValue) - (operate-as cell store! self newValue) - (array-set! self pos newValue) - (set! pos (+ pos 1))) - ((discard self value) - (set! most-recent-discard value)) - ((discarded-value self) most-recent-discard) - ((print self port) - (format port "#<Cell-with-history ~s>" - (fetch self)))))) - -(define-access-operation fetch) -(add-setter fetch store!) -(define foo (make-cell 1)) -(print foo #f) -=> "#<Cell: 1>" -(set (fetch foo) 2) -=> -(print foo #f) -=> "#<Cell: 2>" -(fetch foo) -=> 2 -</pre></td></tr></table><P> - -<A NAME="Textual Conversion Packages"></A> -<HR SIZE="6"> -<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> -<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_3.html#SEC21"> << </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> >> </A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> -<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> -</TR></TABLE> -<BR> -<FONT SIZE="-1"> -This document was generated -by <I>Steve Langasek</I> on <I>January, 10 2005</I> -using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A> -</FONT> - -</BODY> -</HTML> |