Online Book Reader

Home Category

Beautiful Code [280]

By Root 5102 0
system, developed by Clinger, Dybvig, Hieb, and Rees for the Revised Report on Scheme.[**] The simple pattern-based nature of the syntax-rules system permits it to be implemented easily and efficiently.[] Unfortunately, it also limits the utility of the mechanism, so that many useful syntactic abstractions are either difficult or impossible to write.

[**] "Revised report on the algorithmic language Scheme," William Clinger and Jonathan Rees, editors, LISP Pointers, Vol. 4, No. 3, pp. 1–55, July–September 1991.

[] "Macros that work," William Clinger and Jonathan Rees, Conference Record of the Eighteenth Annual ACM Symposium on Principles of Programming Languages, pp. 155–162, January 1991.

The syntax-case system[] was developed to address the shortcomings of the original algorithm without the limitations of syntax-rules. The system supports local macro bindings and operates with constant overhead, yet allows macros to use the full expressive power of the Scheme language. It is upwardly compatible with syntax-rules, which can be expressed as a simple macro in terms of syntax-case, and it permits the same pattern language to be used even for "low-level" macros for which syntax-rules cannot be used. It also provides a mechanism for allowing intended captures—i.e., allowing hygiene to be "bent" or "broken" in a selective and straightforward manner. In addition, it handles several practical aspects of expansion that must be addressed in a real implementation, such as internal definitions and tracking of source information through macro expansion.

[] "Syntactic abstraction in Scheme," R. Kent Dybvig, Robert Hieb, and Carl Bruggeman, Lisp and Symbolic Computation, Vol. 5, No. 4, pp. 295–326, 1993.

This all comes at a price in terms of the complexity of the expansion algorithm and the size of the code required to implement it. A study of a complete implementation in all its glory is therefore beyond the scope of this chapter. Instead, we'll investigate a simplified version of the expander that illustrates the underlying algorithm and the most important aspects of its implementation.

25.1. Brief Introduction to syntax-case

We'll start with a few brief syntax-case examples, adapted from the Chez Scheme Version 7 User's Guide (R. Kent Dybvig, Cadence Research Systems, 2005). Additional examples and a more detailed description of syntax-case are given in that document and in The Scheme Programming Language, Third Edition.

The following definition of or illustrates the form of a syntax-case macro definition:

(define-syntax or

(lambda (x)

(syntax-case x ()

[(_ e1 e2)

(syntax (let ([t e1]) (if t t e2)))])))

The define-syntax form creates a keyword binding, associating the keyword or in this case with a transformation procedure, or transformer. The transformer is obtained by evaluating, at expansion time, the lambda expression on the righthand side of the define-syntax form. The syntax-case form is used to parse the input, and the syntax form is used to construct the output, via straightforward pattern matching. The pattern (_ e1 e2) specifies the shape of the input, with the underscore (_) marking where the keyword or appears, and the pattern variables e1 and e2 bound to the first and second subforms. The template (let([te1]) (iftte2)) specifies the output, with e1 and e2 inserted from the input.

The form (syntax template) may be abbreviated to #'template, so the previous definition may be rewritten as follows:

(define-syntax or

(lambda (x)

(syntax-case x ()

[(_ e1 e2)

(syntax (let ([t e1]) (if t t e2))])))

Macros may also be bound within a single expression via letrec-syntax.

(letrec-syntax ([or (lambda (x)

(syntax-case x ()

[(_ e1 e2)

#'(let ([t e1]) (if t t e2))]))])

(or a b))

Macros can be recursive (i.e., expand into occurrences of themselves), as illustrated by the following version of or that handles an arbitrary number of subforms. Multiple syntax-case clauses are required to handle the two base cases and the recursion case:

(define-syntax or

(lambda (x)

(syntax-case

Return Main Page Previous Page Next Page

®Online Book Reader