The Macrological Fascicle

Editor’s introduction to this fascicle

Note: This introduction will not appear in the final report.

Lisp was the first language to incorporate macros operating on the syntax tree of a program, rather than the text of its source code; Scheme was the first language to add automatic hygiene to such a system. This first fascicle in the development of the seventh revision of the report on Scheme therefore builds on six decades of research and innovation in which Scheme and its predecessors have played an active role throughout. Indeed, the new features added to macros in this fascicle were all pioneered in implementations of Scheme.

Hygienic macros were first mentioned in a Scheme report in an optional appendix to the R4RS. Compared to R4RS, the macro system defined by this fascicle adds only what might be called refinements of the original concept:

The R6RS divided its treatment of macros between the main report (which treated the high-level syntax-rules system and the binding of syntax keywords to transformers) and the report on standard libraries (which actually defined what a transformer is, as well as syntax objects and syntax-case). Neither document contained a complete explanation of the core semantics of macros and expansion alone. In contrast, since the R7RS volume on standard libraries (internally called Batteries) is intended to be entirely implementable in terms of the Foundations, this fascicle explains the entire macro system of R7RS Large. The standard libraries report of R6RS also presented the syntax-case system as a high-level system, without providing enough lower-level features to allow it to be implemented as a user library; this fascicle, however, contains sufficient primitives in the sections on syntax objects and syntax transformation to allow the syntax-case form to be implemented as derived syntax. Therefore, it is perhaps better not to speak of the R7RS macro system as being based on syntax-case as R6RS’s was, but rather based on syntax objects, as the low-level system in the appendix to the R4RS was.

Since extensions to Scheme macros beyond the syntax-rules system provided by the small language have been among the most controversial proposals made for changes in the Scheme language in the last two decades, I hope this fascicle will address these controversies by showing how the popular syntax-rules system is built up, from a theoretical hygiene model, through an implementation of the model on syntax objects processed by transformer procedures; and how finally, with the addition of the pattern matcher from syntax-rules, a specification of the entire syntax-case system is reached, with syntax-rules itself being a trivial transformation thereof. The tools provided in the first three chapters of this fascicle are sufficient to implement the high-level systems of R5RS and R6RS specified in chapters 4 and 5. A sample implementation which demonstrates this will be provided in due course.

What implementations need to do to support this fascicle

Implementations which do not support syntax-case as specified by the R6RS will need to adopt it, either by completely replacing their expanders or by adapting their existing ones. Experience from implementations which have already made the switch shows that the former is generally the easier approach in practice. A non-normative appendix to this fascicle shows how macros written for the explicit renaming system, the most common low-level implementation of macros besides syntax-case, can be accommodated by expanders written for syntax-case; alternatively, van Tonder (2006) implements a version of the syntax-case system which includes native support for a similar version of explicit renaming to that shown in the appendix.

This fascicle deprecates the R6RS’s provisions for explicit phasing. Implementations which use explicit phasing and restrict all identifier bindings to the phase at which they were created will need to switch to implicit phasing (ignoring the phase declarations on imports specified by the R6RS) and allow uses of syntax defined in previous phases.

Compared to the versions of syntax-case and syntax-rules in the R6RS, this fascicle allows renaming the ellipsis (section 4.5) as well as using the ellipsis and underscore as pattern literals, as in the small language report’s syntax-rules. Existing implementations of the pattern matcher will need to be extended to support these features.

This fascicle further extends the R6RS macro system with the addition of lexically-scoped identifier properties (section 2.5) and syntax parameters (section 2.3), both of which require support from the expander.

This fascicle also adds a number of procedures and syntax forms from the R4RS low-level macro system for which the R6RS offered no equivalent, including quote-syntax (equivalent to R6RS’s syntax without pattern variable substitution). Some of these can be implemented portably in terms of the R6RS higher-level constructs.

The final division of the R7RS Large Foundations into libraries will be decided at a later stage. The library name (r7rs-drafts macro-fascicle) is assigned to a temporary library containing all bindings specified in this fascicle, intended for experiments only. These bindings may change incompatibly if this fascicle is updated before the final report is issued. Production code should not depend on this library, and implementations should not support it any more once the final R7RS Large specification is ratified.

Changes in this fascicle compared to the source texts

The main source for the contents of this fascicle is the Yellow Ballot on macros and syntactic constructs held between October 2021 and February 2022 under the chairship of John Cowan. That ballot resulted in the adoption into R7RS Large of the R6RS Standard Libraries chapter on syntax-case, the R6RS identifier-syntax transformer specifier, and the SRFIs 139 (syntax parameters), 188 (splicing-let-syntax and splicing-letrec-syntax), and 213 (identifier properties), besides a number of other proposals which will be incorporated into future fascicles.

Compared to R7RS small and the source documents adopted under the Yellow Ballot, the following substantive changes and additions have been made:

The R6RS condition system has also been implicitly adopted, following informal consensus of WG2 members.