2

は、syntax-parameterが別の識別子のエイリアスとして動作するようにsyntax-parameterize、 と組み合わせて一般的に使用されます。make-rename-transformerp

#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たパターン変数のエイリアスを作成しようとすると、期待どおりに機能しません。tmpwith-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ですか?

4

1 に答える 1

2

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

rename-transformer-parameter の初期値は rename-transformer でなければならないため、トランスフォーマー バインディングとしてでp-init識別子を使用できます。#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)>
于 2016-08-30T18:46:13.423 に答える