Previous: , Up: stdlib syntax-case intro   [Index]


5.12.1.5 A quick look at the expander

Macro transformers are ordinary Scheme functions, which are written in an R6RS–compatible Scheme language; the only difference from ordinary functions, is that: transformer definitions are evaluated at expand time, while ordinary function definitions are evaluated at run time. We take a look at how the expander works, avoiding almost all the details and focusing on the languages.

Let’s define a simple library to be used as language for run time:

#!r6rs
(library (language-for-run)
  (export write newline quote define)
  (import (rnrs)))

and a simple library to be used as language for expand time:

#!r6rs
(library (language-for-expand)
  (export lambda syntax)
  (import (rnrs)))

we use them in the following library, where we also import define-syntax for run time:

#!r6rs
(library (the-library)
  (export doit)
  (import (for (language-for-run) run)
    (for (language-for-expand) expand)
    (for (only (rnrs) define-syntax) run))

  (define (doit)
    (write (the-macro))
    (newline))

  (define-syntax the-macro
    (lambda (stx)
      (syntax (quote (1 2 3)))))
  )

we can run the code with the following program:

#!r6rs
(import (the-library))
(doit)

Let’s point our attention to (the-library). After parsing the import and export clauses, the expander scans the library body; the define-syntax identifier is recognised as the one from (rnrs), so the transformer expression on its right–hand side:

(lambda (stx)
  (syntax (quote (1 2 3))))

is extracted and (not true, but we have to start from somewhere) we can imagine it being evaluated with (notice the import levels):

(define the-transformer
  (eval '(lambda (stx)
           (syntax (quote (1 2 3))))
        (environment
          '(for (language-for-run)    (meta -1))
          '(for (language-for-expand) run))))

what’s left of the library’s body is:

(define (doit)
  (write (the-macro))
  (newline))

which is scanned for uses of the-macro; the use is found and the transformer function applied to a syntax object holding (the-macro); the return value is a syntax object holding the quoted list (1 2 3), which is inserted in the body:

(define (doit)
  (write (quote (1 2 3)))
  (newline))

The body can now be evaluated using bindings from (language-for-run).


Previous: , Up: stdlib syntax-case intro   [Index]