The following example has some tricky hygiene issues that I don't quite understand. The point of the code is to have a form that creates macros by analyzing the pattern and template.
The issue is why do I have to use a name other than 'name' for the pattern variable on the line where it says 'HERE'. If I use the 'name' pattern variable then the syntax-parse form generated by 'make-transformer' will use the wrong lexical context for the literal set. I don't see how the lexical context of the outer 'name' differs from the inner 'new-name', other than the 'new-name' has an extra mark on it. Is that the issue? I tried all sorts of debugging techniques but I can't tell if 'name' has a different lexical context than 'new-name'. I see that marks affect 'bound-identifier=?' but they don't seem to effect 'free-identifier=?' which is what syntax/parse uses to compare literals. #lang racket (require (for-syntax syntax/parse) (for-meta 2 racket/base syntax/parse)) ;; defines a literal and a literal-set that contains the literal (module literals racket/base (require syntax/parse) (provide literal1 literals) (define literal1 0) (define-literal-set literals (literal1))) (module transformer racket/base (require (for-syntax syntax/parse (submod "." ".." literals) racket/base) racket/splicing (for-meta 2 syntax/parse racket/base)) (begin-for-syntax (define-syntax (make-transformer stx) (syntax-parse stx [(_ name pattern template) #'#'(lambda (stx) (syntax-parse stx #:literal-sets ([literals #:at name]) [pattern template]))]))) (provide define-new-syntax) (define-syntax (define-new-syntax stx) (syntax-parse stx [(_ name pattern template) #'(splicing-let-syntax ([make (lambda (stx) (syntax-parse stx [(_ new-name) ;; HERE! If you change this to 'name' it will break (with-syntax ([output (make-transformer name pattern template)]) #'(define-syntax new-name output))]))]) ; change to 'name' too (make name))]))) (require (submod "." literals) (for-syntax (submod "." literals)) (for-meta 2 (submod "." literals)) (submod "." transformer)) (begin-for-syntax (define-syntax (test stx) (syntax-parse stx #:literal-sets (literals) [(_ literal1) #''ok]))) ;; if `literal1' isn't matched as a literal then the call to ;; (test literal1) will fail (define-new-syntax x [_ literal1] (begin (test literal1) #'0)) (x literal1) More explanation about this code: It was recommended to me that the code which analyzes the pattern and template should execute at a phase higher than the phase of the pattern/template. Since the macro is defined at phase 0 the pattern and template live in phase 1 and should be analyzed in phase 2. I cannot just invoke a macro inside the body of 'define-new-syntax' on the 'pattern' and 'template' parameters because then the macro would get the literal syntax objects #'pattern and #'template instead of the syntax they are bound to. As in (define-syntax (define-new-syntax stx) (syntax-parse stx [(_ name pattern template) (analyze pattern template)])) Nor would it be right to make 'analyze' a function at phase 1 and invoke it as (analyze #'pattern #'template) because I need to execute analyze at phase 2. I get to phase 2 by using a let-syntax trampoline in the output of the 'define-new-syntax' macro. The 'pattern' and 'template' variables will have been replaced with their matched syntax as appropriate so the 'make-transformer' macro will operate on the arguments used at the 'define-new-syntax' use-site. The resulting 'x' macro does nothing except invoke a phase 1 macro. This test is necessary to insure that 'literal1' was matched as a literal and not a pattern variable. On 05/17/2012 02:52 PM, Jon Rafkind wrote: > Ok I see from the syntax/parse source that it uses lctx as the first argument > to datum->syntax, so that mostly answers my question. > > On 05/17/2012 02:41 PM, Jon Rafkind wrote: >> What exactly are the semantics of #:at inside a #:literal-sets ([x #:at y]) ? >> >> From the docs " If the #:at keyword is given, the lexical context of the >> lctx term is used to determine which identifiers in the patterns are treated >> as literals;". In what way is 'lctx' used? >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users
____________________ Racket Users list: http://lists.racket-lang.org/users