Macros That Work
================
`(require 'macros-that-work)'
`Macros That Work' differs from the other R4RS macro implementations
in that it does not expand derived expression types to primitive
expression types.
- Function: macro:expand expression
- Function: macwork:expand expression
Takes an R4RS expression, macro-expands it, and returns the result
of the macro expansion.
- Function: macro:eval expression
- Function: macwork:eval expression
`macro:eval' returns the value of EXPRESSION in the current top
level environment. EXPRESSION can contain macro definitions.
Side effects of EXPRESSION will affect the top level environment.
- Procedure: macro:load filename
- Procedure: macwork:load filename
FILENAME should be a string. If filename names an existing file,
the `macro:load' 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 `macro:load' procedure does not affect the
values returned by `current-input-port' and `current-output-port'.
References:
The `Revised^4 Report on the Algorithmic Language Scheme' 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.
Macros That Work. Clinger and Rees. POPL '91.
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.
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)
Definitions
-----------
Scope of an ellipsis
Within a pattern or template, the scope of an ellipsis (`...') is
the pattern or template that appears to its left.
Rank of a pattern variable
The rank of a pattern variable is the number of ellipses within
whose scope it appears in the pattern.
Rank of a subtemplate
The rank of a subtemplate is the number of ellipses within whose
scope it appears in the template.
Template rank of an occurrence of a pattern variable
The template rank of an occurrence of a pattern variable within a
template is the rank of that occurrence, viewed as a subtemplate.
Variables bound by a pattern
The variables bound by a pattern are the pattern variables that
appear within it.
Referenced variables of a subtemplate
The referenced variables of a subtemplate are the pattern
variables that appear within it.
Variables opened by an ellipsis template
The variables opened by an ellipsis template are the referenced
pattern variables whose rank is greater than the rank of the
ellipsis template.
Restrictions
------------
No pattern variable appears more than once within a pattern.
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.
Every ellipsis template must open at least one variable.
For every ellipsis template, the variables opened by an ellipsis
template must all be bound to sequences of the same length.
The compiled form of a RULE is
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
where V and E are unforgeable values.
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.
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.