Previous: stdlib syntax-case violations, Up: stdlib syntax-case [Index]
Using datum->syntax
, it is even possible to break hygiene
entirely and write macros in the style of old Lisp macros. The
lisp-transformer
procedure defined below creates a transformer
that converts its input into a datum, calls the programmer’s procedure
on this datum, and converts the result back into a syntax object scoped
where the original macro use appeared:
(define (lisp-transformer proc) (lambda (stx) (syntax-case stx () ((key . rest) (datum->syntax #'key (proc (syntax->datum stx)))))))
This transformer can be used as follows, first create a library with the definition in it:
(library (lisp-trans) (export lisp-transformer) (import (rnrs)) (define (lisp-transformer proc) (lambda (stx) (syntax-case stx () ((key . rest) (datum->syntax #'key (proc (syntax->datum stx))))))))
then import the library for the ‘expand’ phase; the following example shows what is handed to the client procedure:
(import (rnrs) (for (lisp-trans) expand)) (define-syntax print-it (lisp-transformer (lambda (thing) (write thing) (newline) #f))) (print-it (1 2 3)) -| (print-it (1 2 3))
notice that the macro use prints the value of thing, then returns
#f
which is evaulated in place of the macro use and the result is
#f
itself.
Now we shold understand the following:
(import (rnrs) (for (lisp-trans) expand)) (define-syntax even (lisp-transformer (lambda (thing) `(begin (write (quote ,(map even? (cadr thing)))) (newline))))) (even (1 2 3)) -| (#f #t #f)
the macro use (even (1 2 3))
is equivalent to:
(begin (write (quote (#f #t #f))) (newline))
that is, the form returned by the client procedure is evaluated in place of the macro use.
Previous: stdlib syntax-case violations, Up: stdlib syntax-case [Index]