別の識別子の別名としてp
挙動構文パラメータようsyntax-parameterize
は一般make-rename-transformer
と組み合わせて使用されている:tmp
はlet
によって結合識別子であるとして上記のコードは、うまく機能構文パラメータは構文パターン変数を指していますか?
#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
。しかし、もし私が期待通りにp
with-syntax
に縛らパターン変数tmp
の別名、それが動作しないようにしよう:
#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)
にバインドした場合、それは動作しますfine:
#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
を使用してパターン変数の衛生エイリアスを作成するにはどうすればよいですか?
これは、何のバグではありません。 'syntax-parameterize'のドキュメンテーションは、' 'expr'が' 'make-rename-transformer''の結果を生成した場合、' id'をターゲット識別子の使用に展開するマクロとして使うことができますが、 'syntax- idの 'local-value'はターゲットの値を生成しません。"なぜこの制限が存在するのかは完全にはわかりませんが、説明を見つけるのは面白いでしょう。構文パラメータに関する論文には言及していないようです。私の推測では、構文パラメータ自体が 'syntax-local-value'と直接に互換性を持たない間接を使用するということです。 –
その場合、構文変換パラメータをリネームトランスフォーマのように調べるのは 'syntax'の仕事でしょうか? –
私はそうは思わない。個人的には、これを適切に処理することが何かの仕事であれば、 'syntax-local-value'を使用するすべてのマクロがシンタックスパラメータの特別な処理を追加する必要があるため、' syntax-local-value'と思うでしょう。もちろん、C言語で 'syntax-local-value'が実装されている間にRacketで構文パラメータが実装されるため、複雑になるかもしれませんが、ここでより良い協力が必要なようです。 –