通常syntax-parameterize
与 结合使用,make-rename-transformer
以便语法参数p
表现为另一个标识符的别名:
#lang racket
(require racket/stxparam)
(define-syntax-parameter p #f)
(define-syntax (test-1-p stx)
(syntax-case stx ()
[(_ body)
#'(let ([tmp 123])
(syntax-parameterize ([p (make-rename-transformer #'tmp)])
body))]))
(test-1-p p) ;; prints 123
上面的代码运行良好,由 .tmp
绑定的标识符也是如此let
。但是,如果我尝试为由 绑定p
的模式变量创建别名,则它不会按预期工作:tmp
with-syntax
#lang racket
(require racket/stxparam)
(define-syntax-parameter p #f)
(define-syntax (test-2-p stx)
(syntax-case stx ()
[(_ body)
#'(with-syntax ([tmp #'(foo 123)])
(syntax-parameterize ([p (make-rename-transformer #'tmp)])
body))]))
(test-2-p #'p) ;; gives #'p, instead of #'(foo 123)
相反,如果我声明一个p-unhygienic
语法,并将其绑定到(make-rename-transformer #'tmp)
,那么它可以正常工作:
#lang racket
(define-syntax (test-3-p stx)
(syntax-case stx ()
[(_ body)
#`(with-syntax ([tmp #'(foo 123)])
(define-syntax #,(syntax-local-introduce #'p-unhygienic)
(make-rename-transformer #'tmp))
body)]))
(test-3-p #'p-unhygienic) ;; gives #'(foo 123), as expected
如何使用 为模式变量创建卫生别名syntax-parameterize
?