Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 3, the unsupported old release. You're almost certainly looking for [[/eggref/4/syntax-case|the CHICKEN 4 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-4.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. [[tags: egg] == syntax-case Portable syntax-case macro and module system == Usage <enscript highlight="scheme"> (require-extension syntax-case) </enscript> Alternatively you can pass {{-require-extension syntax-case}} at the command-line to {{chicken}} (or {{-R syntax-case}} for {{csc}}). == Introduction This is a port of the ``portable syntax-case'' macro expander by Dybvig, Waddel, Hieb and Bruggeman. This facility provides fully compliant R5RS {{syntax-rules}} and the much more powerful {{syntax-case}} form. A comprehensive explanation is best found in the [[http://www.scheme.com/csug/|Chez Scheme Users Guide]], specifically [[http://www.scheme.com/csug/syntax.html#./syntax:h5|Section 10.5 - Modules]]. What follows is an informal introduction to that module system. (This introduction to modules is courtesy of Scott G. Miller) 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. === Overview The basic unit of modularization is a module. A typical module definition has this appearance: <enscript highlight="scheme"> (module foo (bar baz) (import boo1) (import boo2) (include "file.scm") (define (bar x) ...) (define-syntax baz ...) (define (something-else ...) ...) (do-something) (do-something-else)) </enscript> A module definition consists of a name ({{foo}}), a list of exports ({{bar}} and {{baz}}) 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 {{boo1}} and {{boo2}}) 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. All identifiers appearing in the export list must be defined or {{define-syntax}}ed in the body of the module, or imported from another module. It is recommended to clearly separate modularization from actual code. The best way to accomplish this is to * List all imports in the module body rather than in included files * Include all files directly from the module body, avoiding nested includes * Place all definitions and expressions in included files, avoiding them in the module body 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). === Modularizing Existing Code 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: * All definitions must appear before all expressions, * 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. 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: <enscript highlight="scheme"> (define (foo) 1) (define bar (foo)) (do-some-stuff) (define (baz) (bar)) ==> (define (foo) 1) (define bar) (define (baz) (bar)) (set! bar (foo)) (do-some-stuff) </enscript> 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: * If a non-definition is encountered, append it to the expression list * 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 * Otherwise, i.e. for an ordinary definition, append it to the definition list The concatenation of the resulting definition list with the expression list makes a suitable module body. === Evaluation Modules are lexically scoped. It is possible to define modules inside lambdas and inside other modules and to export modules from modules. Example: <enscript highlight="scheme"> (define (f c) (module foo (bar) (module bar (baz) (define (baz x y) (- x y)) (display "defining baz\n"))) (if (> c 0) (let ((a 1)) (import foo) (let loop ((b c)) (import bar) (if (> b 0) (loop (baz b a)) (f (- c 1))))))) </enscript> 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. 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. === Notes The following procedures and syntactic forms are supported: * {{bound-identifier=?}} * {{datum->syntax-object}} * {{define-syntax}} * {{fluid-let-syntax}} * {{free-identifier=?}} * {{generate-temporaries}} * {{identifier?}} * {{identifier-syntax}} * {{import}} * {{import*}} * {{import-only}} * {{let-syntax}} * {{letrec-syntax}} * {{module}} * {{syntax}} * {{syntax-case}} * {{syntax-object->datum}} * {{syntax-rules}} * {{with-syntax}} The alternative form: <enscript highlight="scheme"> (define-syntax (keyword var) (syntax-case var (...) ...) ) </enscript> is allowed for {{define-syntax}}. {{(import* MODULE IMP ...)}} allows selective imports. Only the identifiers {{IMP ...}} will be imported from {{MODULE}}. {{IMP}} may be a list of the form {{(NEW OLD)}} where the exported identifier {{OLD}} will be imported under the name {{NEW}}. When {{import}}, {{import*}} or {{import-only}} is used with an argument that names a module that is currently not defined, then the current {{include-path}} (and the {{repository-path}} as well) is searched for a source-file of the same name (possibly with the extension {{.scm}}), which (if found) will be ``visited'' (it's module- and syntax-definitions are processed) using the procedure {{visit}}. {{define-syntax}} can not be used inside an {{eval-when}} form. No builtin modules are provided. The {{run-time-macros}} declaration (and compiler option) has no effect with syntax-case macros All non-standard CHICKEN syntax is supported, including {{define-macro}} {{define-method}} is only valid for generic functions that have been previously defined with {{define-generic}} When used during compilation, the non-standard syntax for interfacing to foreign code is loaded automatically {{define-constant}} and {{define-inline}} are treated specially. To export undecorated module bindings from a compilation unit, use the {{export-toplevel}} form: <enscript highlight="scheme"> (module (foo) (define (foo) 'ok) (export-toplevel foo) ) ; global variable `foo' is now visible from outside </enscript> ({{(export-toplevel}} also accepts {{(VARIABLE EXPORTEDVARIABLE)}} which exports a variable under a different name) The idea is to allow using modules in separate compilation units while interfacing with code that doesn't use the syntax-case macro (and module) system. Note that {{export-toplevel}} does not work for syntax. == Example Here is a small example that demonstrates separate compilation: Let's say we have one file {{foo.scm}} that defines a module: <enscript highlight="scheme"> (module foo (pr (bar baz)) (define pr print) (define baz 99) (define-syntax bar (syntax-rules () ((_ x) (list baz 'x)) ) ) ) </enscript> and another that uses it ({{use-foo.scm}}): <enscript highlight="scheme"> (load "foo.so") ; (require 'foo) would also work (import foo) (pr (bar hello)) </enscript> Compiling the files like this will lead to one dynamically loadable library and a plain executable: <enscript highlight="sh"> $ csc -s -R syntax-case foo.scm $ csc -R syntax-case use-foo.scm $ use-foo (99 hello) </enscript> == Additional procedures <procedure>(visit FILENAME)</procedure> Reads all toplevel expressions from the given file and expands all syntax, extracting module- and syntax-information to be subsequently used during the current compilation or interpretation of modules. <procedure>(debug-expand EXP)</procedure> Macro-expands the expression {{EXP}} and shows each expansion step, giving a choice of expanding the expression completely, advance to the next expansion step or aborting the expansion. This might be a useful tool for debugging complex macros. The implementation of {{cond}} is [[http://srfi.schemers.org/srfi-61/|SRFI-61]] compliant. == Authors R. Kent Dybvig, Oscar Waddell, Bob Hieb, Carl Bruggeman == License Copyright (c) 1992-2002 Cadence Research Systems Permission to copy this software, in whole or in part, to use this software for any lawful purpose, and to redistribute this software is granted subject to the restriction that all copies made of this software must include this copyright notice in full. This software is provided AS IS, with NO WARRANTY, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES OF ANY NATURE WHATSOEVER. == Requirements None == Version History * 6.9995: handles (but ignores) non-symbolic exports from exports file; removed {{critical-section}} * 6.9994: removed use of obsolete {{compress-literals}} initializer [Thanks to Mario and Salmonella] * 6.9993: replaced use of deprecated {{test-feature?}} * 6.9992: {{import}} didn't parse .exports files properly * 6.9991: Fixed bug in definition of "include" [Thanks to Dan Muresan] * 6.9990: Treat <tt>define-constant</tt> and <tt>define-inline</tt> special [Kon Lovett] * 6.9989: Added <tt>optional</tt> as new name for <tt>:optional</tt> * 6.9988: Uses slightly more efficient way of generating lexical aliases * 6.9987: Generated identifiers include original name for better debugging [Thanks to Andre Kuehne] * 6.9986: {{include}} wasn't using the resolved pathname but the original filename [Kon Lovett] * 6.9985: {{define-record-type}} doesn't bind type identfier anymore * 6.9984: {{include}} shows message in verbose mode * 6.9983: Added {{import*}}, single-value case handling for {{set!-values}} and {{define-values}} * 6.9982: Improved {{:optional}} expansion for unsafe code * 6.9981: Basic support for extracting imports from {{export}} extension info / {{.exports}} files * 6.998: Registers feature {{syntax-rules}} * 6.997: Extended {{export-toplevel}} * 6.996: Tiny bugfix in expansion of {{cond-expand}} * 6.995: Expansion of {{define-method}} was using internal lambda form that the expander doesn't like * 6.994: Added {{export-toplevel}} * 6.993: Support for [[http://srfi.chemers.org/srfi-61/|SRFI-61]]. * 6.992: Added support for {{define-for-syntax}} * 6.991: The implementation of {{let*-values}} is now [[http://srfi.chemers.org/srfi-11/|SRFI-11]] compliant. * 6.99: Only loads non-standard syntax when {{#:standard-syntax}} feature is not defined * 6.98: {{let-values}} now accepts formals of the form {{<variable>}} and {{(<variable> ... <variable> . <variable>)}} as specified in SRFI-11 * 6.97: When visiting a file, {{include}} also searches the extension repository * 6.96: Ported to internal macroexpand-hooking version in 2.111 * 6.95: Added documentation and version info to setup script * 6.9.4: {{include}} doesn't use {{##sys#read-line-counter}} anymore * 6.9.3: Uses preinstalled {{chicken-ffi-macros.scm}}
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you add 16 to 9?