2016-08-30 5 views
2

別の識別子の別名としてp挙動構文パラメータようsyntax-parameterizeは一般make-rename-transformerと組み合わせて使用​​されている:tmpletによって結合識別子であるとして上記のコードは、うまく機能構文パラメータは構文パターン変数を指していますか?

#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 

。しかし、もし私が期待通りにpwith-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を使用してパターン変数の衛生エイリアスを作成するにはどうすればよいですか?

答えて

2

これは興味深いケースですが、同じことを期待していました。これはどこかのバグか制限のどちらかです。よく分かりません。いずれにしても、回避策としてdefine-rename-transformer-parameterフォームが提供されています。

rename-transformer-parameterの初期値は名前変更トランスでなければなりません。という識別子を#fに使用することができます。文脈では

(define-syntax p-init #f) 
(define-rename-transformer-parameter p (make-rename-transformer #'p-init)) 

:それは* *制限ですが

#lang racket 

(require racket/stxparam) 
(define-syntax p-init #f) 
(define-rename-transformer-parameter p (make-rename-transformer #'p-init)) 

(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) ; #<syntax:10:28 (foo 123)> 
+1

これは、何のバグではありません。 'syntax-parameterize'のドキュメンテーションは、' 'expr'が' 'make-rename-transformer''の結果を生成した場合、' id'をターゲット識別子の使用に展開するマクロとして使うことができますが、 'syntax- idの 'local-value'はターゲットの値を生成しません。"なぜこの制限が存在するのかは完全にはわかりませんが、説明を見つけるのは面白いでしょう。構文パラメータに関する論文には言及していないようです。私の推測では、構文パラメータ自体が 'syntax-local-value'と直接に互換性を持たない間接を使用するということです。 –

+0

その場合、構文変換パラメータをリネームトランスフォーマのように調べるのは 'syntax'の仕事でしょうか? –

+0

私はそうは思わない。個人的には、これを適切に処理することが何かの仕事であれば、 'syntax-local-value'を使用するすべてのマクロがシンタックスパラメータの特別な処理を追加する必要があるため、' syntax-local-value'と思うでしょう。もちろん、C言語で 'syntax-local-value'が実装されている間にRacketで構文パラメータが実装されるため、複雑になるかもしれませんが、ここでより良い協力が必要なようです。 –

関連する問題