source: project/release/3/syntax-case/syntax-case.html @ 8291

Last change on this file since 8291 was 8291, checked in by Kon Lovett, 12 years ago

Rmvd compress literals decl.

File size: 13.5 KB
Line 
1<html>
2<head><title>Eggs Unlimited - syntax-case</title></head>
3<body>
4
5<center><img src="egg.jpg"></center>
6<center><a href="index.html">back</a></center>
7
8<h2>syntax-case</h2>
9
10<h3>Description:</h3>
11Portable syntax-case macro and module system
12
13<h3>Author:</h3>
14R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman
15
16<h3>Usage:</h3> 
17<pre>
18(require-extension syntax-case)
19</pre>
20
21<p>Alternatively you can pass <code>-require-extension syntax-case</code> at the command-line to
22<code>chicken</code> (or <code>-R syntax-case</code> for <code>csc</code>).
23
24<h3>Download:</h3>
25<a href="syntax-case.egg">syntax-case.egg</a>
26
27<h3>Documentation:</h3>
28
29This is a port of the ``portable syntax-case'' macro expander by Dybvig, Waddel, Hieb and Bruggeman. This
30facility provides fully compliant R5RS <code>syntax-rules</code> and the much more powerful <code>syntax-case</code> form.
31
32<p>A comprehensive explanation is best found in the
33<a href="http://www.scheme.com/csug.html">Chez Scheme Users Guide</a>, specifically
34<a href="http://www.scheme.com/csug/syntax.html#g2187">Section 9.3 - Modules</a>.
35
36<p>What follows is an informal introduction to that module system.
37
38<p>(This introduction to modules is courtesy of Scott G. Miller)
39
40<p>Modules provide an additional level of scoping control, allowing symbolic and syntactic bindings to be bundled in a named or anonymous package. The package can then be imported into any scope, making the bindings contained in the module visible in only that scope.
41
42<p><b>Overview</b>
43
44<p>The basic unit of modularization is a module. A typical module definition has this appearance:
45
46<pre>
47(module foo
48    (bar baz)
49  (import boo1)
50  (import boo2)
51  (include "file.scm")
52  (define (bar x) ...)
53  (define-syntax baz ...)
54  (define (something-else ...) ...)
55  (do-something)
56  (do-something-else))
57</pre>
58
59<p>A module definition consists of a name (<code>foo</code>), a list of exports (<code>bar</code> and <code>baz</code>) and a body. Expressions which can appear in the body of a module are the same as those which can appear in a lambda body. The import form imports bindings from a named module (in this case <code>boo1</code> and <code>boo2</code>) into the current lexical scope. The include form performs a textual inclusion of the source code found in the named file (file.scm). In other words, it works as if the contents of the file had appeared literally in place of the include statement.
60
61<p>All identifiers appearing in the export list must be defined or define-syntaxed in the body of the module, or imported from another module.
62
63<p>It is recommended to clearly separate modularization from actual code. The best way to accomplish this is to
64
65<ul>
66<li>List all imports in the module body rather than in included files
67<li>Include all files directly from the module body, avoiding nested includes
68<li>Place all definitions and expressions in included files, avoiding them in the module body
69</ul>
70
71<p>There are several reasons for this. First, it makes refactoring easier, as one can move relevant code from module to module merely by rewriting the module definitions, leaving the implementation code unchanged. Second, it makes debugging easier, as one can load the implementation code directly into the Scheme system to have access to all bindings, or load the module definition to view the finished, encapsulated exports. Finally, it stylistically separates interface (the modules) from implementation (the included Scheme source).
72
73<p><b>Modularizing Existing Code</b>
74
75<p>Since module bodies are treated like the bodies of lambdas, the R5RS rules of how internal definitions are treated apply to all the definitions in the module body (both ordinary and syntax), including all code included from files. This is often a source of errors when moving code from the top-level into a module because:
76
77<ul>
78<li>All definitions must appear before all expressions,
79<li>The list of definitions is translated into letrec/letrec-syntax, which means it must be possible to evaluate each right-hand side without assigning or referring to the value of any of the variables being defined.
80<li>itemize
81</ul>
82
83<p>This often necessitates re-arranging the code and the introduction of set! expressions. Here is an example of a sequence of top-level definitions/expressions and how they need to be rewritten so that they may appear in a module body:
84
85<pre>
86(define (foo) 1)
87(define bar (foo))
88(do-some-stuff)
89(define (baz) (bar))
90==&gt;
91(define (foo) 1)
92(define bar)
93(define (baz) (bar))
94(set! bar (foo))
95(do-some-stuff)
96</pre>
97
98<p>The general strategy is to go through the list of expressions/definitions from top to bottom and build two lists - one of definitions and one of expressions - as follows:
99
100<ul>
101<li>If a non-definition is encountered, append it to the expression list
102<li>If a "naked" definition (i.e. a definition whose right-hand side is not a function) that refers to a binding defined within the module is encountered, append an empty definition to the definition list and append a set! with the right-hand side expression to the expression list
103<li>Otherwise, i.e. for an ordinary definition, append it to the definition list
104</ul>
105
106<p>The concatenation of the resulting definition list with the expression list makes a suitable module body.
107Evaluation
108
109<p>Modules are lexically scoped. It is possible to define modules inside lambdas and inside other modules and to export modules from modules. Example:
110
111<pre>
112(define (f c)
113  (module foo
114      (bar)
115    (module bar
116        (baz)
117      (define (baz x y) (- x y))
118      (display "defining baz\n")))
119  (if (&gt; c 0)
120      (let ((a 1))
121         (import foo)
122         (let loop ((b c))
123            (import bar)
124            (if (&gt; b 0) (loop (baz b a)) (f (- c 1)))))))
125</pre>
126
127<p>The expressions in a module body get executed at the time and in the context of module definition. So, in the above example, the body of bar containing the display statement is executed once for every call to f rather than once for every iteration of the inner loop containing the import of the bar module.
128
129<p>There are quite a few more things you can do with modules. For instance one can define anonymous modules, which are a short cut for defining a named module and then importing it, import selected bindings from a module and renaming them rather then importing all bindings as is etc etc. For more details again refer to the Chez Scheme user manual.
130
131<p><b>Notes</b>
132
133<ul>
134
135<li>The following procedures and syntactic forms are supported:
136<pre>
137bound-identifier=?
138datum->syntax-object
139define-syntax
140fluid-let-syntax
141free-identifier=?
142generate-temporaries
143identifier?
144identifier-syntax
145import
146import*
147import-only
148let-syntax
149letrec-syntax
150module
151syntax
152syntax-case
153syntax-object->datum
154syntax-rules
155with-syntax
156</pre>
157
158<li>The alternative form
159<pre>
160(define-syntax (keyword var)
161  (syntax-case var (...) ...) )
162</pre>
163is allowed for <code>define-syntax</code>.
164
165<li><code>(import* MODULE IMP ...)</code> allows selective imports. Only the identifiers <code>IMP ...</code>
166will be imported from <code>MODULE</code>. <code>IMP</code> may be a list of the form <code>(NEW OLD)</code>
167where the exported identifier <code>OLD</code> will be imported under the name <code>NEW</code>.
168
169<li> When <code>import</code>, <code>import*</code> or <code>import-only</code>
170is used with an argument that names a module that is currently not defined, then
171the current <code>include-path</code> (and the <code>repository-path</code> as well) is searched for a source-file
172of the same name (possibly with the extension <code>.scm</code>), which (if found)
173will be ``visited'' (it's module- and syntax-definitions are processed) using the
174procedure <code>visit</code>.
175
176<li><code>define-syntax</code> can not be used inside an <code>eval-when</code> form.
177
178<li>No builtin modules are provided.
179
180<li>The <code>run-time-macros</code> declaration (and compiler option) has no effect with syntax-case macros
181
182<li>All non-standard CHICKEN syntax is supported, including <code>define-macro</code>
183
184<li><code>define-method</code> is only valid for generic functions that have been previously defined with
185<code>define-generic</code>
186
187<li>When used during compilation, the non-standard syntax for interfacing to foreign code is loaded automatically
188
189<li><code>define-constant</code> and <code>define-inline</code> are treated specially.
190
191<li>To export undecorated module bindings from a compilation unit, use the <code>export-toplevel</code> 
192form:
193
194<pre>
195(module (foo)
196  (define (foo) 'ok)
197  (export-toplevel foo) )  ; global variable `foo' is now visible from outside
198</pre>
199
200(<code>(export-toplevel</code> also accepts <code>(VARIABLE EXPORTEDVARIABLE)</code> which exports
201a variable under a different name)
202
203<p>The idea is to allow using modules in separate compilation units while interfacing
204with code that doesn't use the syntax-case macro (and module) system.
205<br>Note that <code>export-toplevel</code> does not work for syntax.
206
207</ul>
208
209<p>Here is a small example that demonstrates separate compilation:
210
211<p>Let's say we have one file <code>foo.scm</code> that defines a module:
212
213<pre>
214(module foo (pr (bar baz))
215  (define pr print)
216  (define baz 99)
217  (define-syntax bar
218    (syntax-rules ()
219      ((_ x) (list baz 'x)) ) ) )
220</pre>
221
222<p>and another that uses it (<code>use-foo.scm</code>):
223
224<pre>
225(load "foo.so")   ; (require 'foo) would also work
226
227(import foo)
228(pr (bar hello))
229</pre>
230
231<p>Compiling the files like this will lead to one dynamically loadable library
232and a plain executable:
233
234<pre>
235$ csc -s -R syntax-case foo.scm
236$ csc -R syntax-case use-foo.scm
237$ use-foo
238$ (99 hello)
239</pre>
240
241<p><b>Additional procedures</b>
242
243<p>
244<dl>
245<p><dt><em>(procedure)</em> <code>(visit FILENAME)</code>
246<dd>Reads all toplevel expressions from the given file and expands all syntax, extracting
247module- and syntax-information to be subsequently used during the current compilation or
248interpretation of modules.
249
250<p><dt><em>(procedure)</em> <code>(debug-expand EXP)</code>
251<dd>
252Macro-expands the expression <code>EXP</code> and shows each expansion step, giving a choice
253of expanding the expression completely, advance to the next expansion step or aborting
254the expansion. This might be a useful tool for debugging complex macros.
255</dl>
256
257<p>The implementation of <code>cond</code> is <a href="http://srfi.schemers.org/srfi-61/">SRFI-61</a> compliant.
258
259<h3>Version:</h3>
260<ul>
261
262<li>6.9997 Removed '(compress-literals)' declaration. [Kon Lovett]</li>
263<li>6.9996 Add 'select' syntax. [Kon Lovett]</li>
264<li>6.9995
265handles (but ignores) non-symbolic exports from exports file; removed {{critical-section}}
266<li>6.9994
267removed use of obsolete <code>compress-literals</code> initializer [Thanks to Mario and Salmonella]
268<li>6.9993
269replaced use of deprecated <code>test-feature?</code>
270<li>6.9992
271<code>import</code> didn't parse .exports files properly
272<li>6.9991
273Fixed bug in definition of "include" [Thanks to Dan Muresan]
274<li>6.9990
275Treat <tt>define-constant</tt> and <tt>define-inline</tt> special [Kon Lovett]
276<li>6.9989
277Added <tt>optional</tt> as new name for <tt>:optional</tt>
278<li>6.9988
279Uses slightly more efficient way of generating lexical aliases
280<li>6.9987
281Generated identifiers include original name for better debugging [Thanks to Andre Kuehne]
282<li>6.9986
283<code>include</code> wasn't using the resolved pathname but the original filename [Kon Lovett]
284<li>6.9985
285<code>define-record-type</code> doesn't bind type identfier anymore
286<li>6.9984
287<code>include</code> shows message in verbose mode
288<li>6.9983
289Added <code>import*</code>, single-value case handling for <code>set!-values</code> and <code>define-values</code>
290<li>6.9982
291Improved <code>:optional</code> expansion for unsafe code
292<li>6.9981
293Basic support for extracting imports from <code>export</code> extension info / <code>.exports</code> files
294<li>6.998
295Registers feature <code>syntax-rules</code>
296<li>6.997
297Extended <code>export-toplevel</code>
298<li>6.996
299Tiny bugfix in expansion of <code>cond-expand</code>
300<li>6.995
301Expansion of <code>define-method</code> was using internal lambda form that the expander doesn't like
302<li>6.994
303Added <code>export-toplevel</code>
304<li>6.993
305Support for <a href="http://srfi.chemers.org/srfi-61/">SRFI-61</a>.
306<li>6.992
307Added support for <code>define-for-syntax</code>
308<li>6.991
309  The implementation of <code>let*-values</code> is now <a href="http://srfi.chemers.org/srfi-11/">SRFI-11</a> compliant.
310<li>6.99
311Only loads non-standard syntax when <code>#:standard-syntax</code> feature is not defined
312<li>6.98
313<code>let-values</code> now accepts formals of the form
314<code>&lt;variable&gt;</code> and <code>(&lt;variable&gt; ... &lt;variable&gt;
315. &lt;variable&gt;)</code> as specified in SRFI-11
316<li>6.97
317When visiting a file, <code>include</code> also searches the extension repository
318<li>6.96
319Ported to internal macroexpand-hooking version in 2.111
320<li>6.95
321Added documentation and version info to setup script
322<li>6.9.4
323<code>include</code> doesn't use <code>##sys#read-line-counter</code> anymore
324<li>6.9.3
325Uses preinstalled <code>chicken-ffi-macros.scm</code>
326<li>0.1
327</ul>
328
329<h3>License:</h3>
330<pre>
331Copyright (c) 1992-2002 Cadence Research Systems
332Permission to copy this software, in whole or in part, to use this
333software for any lawful purpose, and to redistribute this software
334is granted subject to the restriction that all copies made of this
335software must include this copyright notice in full.  This software
336is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED,
337INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
338OR FITNESS FOR ANY PARTICULAR PURPOSE.  IN NO EVENT SHALL THE
339AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY
340NATURE WHATSOEVER.
341</pre>
342
343<hr><a href="index.html">back</a>
344
345</body>
346</html>
Note: See TracBrowser for help on using the repository browser.