Today's macro PSA is about macro-generating-macro forms. If you use a macro to generate a transformer then you must be careful about nesting `syntax' forms otherwise you will interpolate templates too many times. Specifically #'#'x will interpolate x twice. Given the following bindings:
chicken = (syntax (egg ...)) pattern = (syntax chicken) The problem is if an additional `syntax' is wrapped around `pattern'. After one interpolation of `syntax' we will have (syntax (egg ...)) At which point `egg' had better be bound as a pattern variable otherwise interpolation will fail. To work around this problem the `quote-syntax' form should be used: #'(quote-syntax pattern) which prevents the (syntax (egg ...)) layer from being interpolated because `quote-syntax' does not do interpolation. The following example demonstrates the issue. On the line 'HERE' the inner syntax should be `quote-syntax' otherwise the following error is produced x.rkt:27:24: syntax: no pattern variables before ellipses in template at: ... in: (_ x ...) To be fair this issue only comes up because I used `make-transformer' in the body of a phase 2 function so the output of `make-transformer' had to have two levels of syntax, because its a macro that should ultimately evaluate to a syntax form. A simpler solution would have been to do #'(define-syntax name (make-transformer pattern action)) So that `make-transformer' only had to return one level of syntax. But anyway I got into this situation for other reasons. #lang racket (require (for-meta 0 racket/splicing) (for-meta 1 syntax/parse) (for-meta 2 syntax/parse racket/base)) (begin-for-syntax (define-syntax (make-transformer stx) (syntax-parse stx [(_ (pattern ...) action) #'#'(lambda (stx) ;; HERE change to #'(quote-syntax (syntax-parse stx [(_ pattern ...) action]))]))) (define-syntax (macro-generator stx) (syntax-parse stx [(_ name pattern action) #'(splicing-let-syntax ([make (lambda (stx) (syntax-parse stx [(_ name) (with-syntax ([transformer (make-transformer pattern action)]) #'(define-syntax name transformer))]))]) (make name))])) (macro-generator foo (x ...) #'(list x ...)) (foo 1 2 3)
____________________ Racket Users list: http://lists.racket-lang.org/users