読者です 読者をやめる 読者になる 読者になる

...

Scheme のマクロ (id:SaitoAtsushi:20100927:1285584328) を書いていて気付いた疑問点を本家 WiLiKi で質問すると回答をもらえた。

齊藤 (2010/09/29 19:46:49 PDT):
syntax-rules のテンプレートについてです。 以下のように書くとエラーになります。

(define-syntax hoge
  (syntax-rules ()
    ((_ r ...)
     (list '(r (r ...)) ...))))

(hoge 1 2 3)

期待する展開形は

(list '(1 (1 2 3)) '(2 (1 2 3)) '(3 (1 2 3)))

です。
... が (r ...) にも掛ってしまうことが原因とは思いますが、 R5RS 的には未定義なんでしょうか? 手元で試してみたところ、 Gauche を含む R5RS 処理系のいくつかではエラーになり、主要な R6RS 処理系では期待通りに展開されるようです。

http://practical-scheme.net/wiliki/wiliki.cgi?Scheme:%E5%88%9D%E5%BF%83%E8%80%85%E3%81%AE%E8%B3%AA%E5%95%8F%E7%AE%B1#H-1l5301jv3m51i

Shiro(2010/10/02 17:33:18 PDT):
はい、これはR5RSでは曖昧で、R6RSで明確化されました。

Pattern variables that occur in subpatterns followed by one or more instances of the identifier ... are allowed only in subtemplates that are followed by as many instances of ....

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_sec_4.3.2

このas manyは「同数の」ですが、文章全体が必要条件を述べているともとれ、その場合 as manyは下限を示していると解釈可能です。テンプレートの方で...が多い場合については 仕様は何も言っていないので、以下のどちらの解釈もOKです。

  • 厳密に解釈して、同数の...でないとエラーにする
  • ... が多い場合は処理系拡張の動作とする

R6RSでは...が多い場合について明示的に許され、振る舞いも定義されました。

If a pattern variable is followed by more ellipses in the subtemplate than in the associated subpattern, the input form is replicated as necessary.

http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.19
http://practical-scheme.net/wiliki/wiliki.cgi?Scheme:%E5%88%9D%E5%BF%83%E8%80%85%E3%81%AE%E8%B3%AA%E5%95%8F%E7%AE%B1#H-1l5301jv3m51i

と、言うわけで先日のマクロは R5RS 的には未定義の振舞いに依存している。 補助マクロを追加してなんとか回避できるかなぁ。
Document ID: bc3ee0f6b638981846554a1bfee789b6