は、syntax-parameterが別の識別子のエイリアスとして動作するように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
ですか?