For Development HEAD DRAFTSearch (procedure/syntax/module):

5.5 構文パラメータ

構文パラメータは、マクロ展開時に動的に構文束縛を置き換えるものです。 束縛フォームはparameterizeに似ています(パラメータ参照)が、 マクロ展開時のみに作用します。 これを使うと、他のマクロに影響を与えるマクロを衛生的に書くことができます。 構文パラメータはSRFI-139で定義されました。

例えば、(block <body> ...)というマクロを考えてみます。 これは<body>を順番に実行します。<body>の中で、 別のマクロ(return <expr>)を呼び出すことができて、 その場合、<expr>が評価され、それを値として直ちに(block ...)から 脱出します。

言ってみれば、マクロblockはマクロreturnの振る舞いを変える必要がある わけです。これは次のように書くことができるでしょう。

(define-syntax block
  (er-macro-transformer
    (^[f r c]
      (quasirename r
       `(let/cc ,'return ,@(cdr f)))))

(block (print 1) (print 2) (return 'oops) (print 4))
 ⇒ print 1, 2, and then returns oops

ただ、この定義ではreturnを非衛生的に挿入する必要があることに注目してください。 これは、returnを別の目的で使いたい他のライブラリがあった場合、 一緒に使うと衝突してうまくいかないかもしれません。

構文パラメータを使うと、衛生的に書くことができます:

(define-syntax-parameter return
  (syntax-rules ()
    ((_ . _) (syntax-error "return outside block"))))

(define-syntax block
  (syntax-rules ()
    ((_ body ...)
     (let/cc %return
       (syntax-parameterize ((return (syntax-rules ()
                                       ((_ expr) (%return expr)))))
         body ...)))))

blockの中のreturnは、define-syntax-parameterで 定義されたreturnと同じ束縛を参照している時のみ効果を持ちます。 例えば上記コードをライブラリにして、ユーザがプレフィックスつきでそれを インポートしたとしましょう。 その場合、非局所的脱出をするreturnをプレフィクスつきになり、 そのモジュールで定義される別のreturnと共存できます。

(use block :prefix b:)

(define return ...)

(b:block
  ...
  (return ...)  ; 現在のモジュールの 'return' を参照
  ...
  (b:return 'oops) ; blockから抜ける return の呼び出し
  ...
  )
Special Form: define-syntax-parameter name transformer-spec

[SRFI-139] define-syntaxと同様に、transformer-specで作られるマクロを nameに束縛します。それに加えて、束縛が構文パラメータであることが記録され、 syntax-parameterizeで置き換えることができるようになります。

与えられたtransformer-specは、namesyntax-parameterizeで再束縛されていない場合のデフォルトのマクロとして 動作します。transformer-specに使える形式は define-syntaxのものと同じです。

Special Form: syntax-parameterize ((key transformer-spec) …) body …

[SRFI-139] keyは構文パラメタに束縛された識別子でなければなりません。 このフォームは、keyの構文束縛をtransformer-specで指定されるものに 置き換えて、body …を実行します。 この再束縛はマクロ展開時の動的スコープで有効です (実行時の動的スコープとは関係ないことに注意してください)。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT