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]