スロット番号付き cut を R5RS 範囲内で書く

昨日はスロット番号付きの cut を syntax-rules で書いた。

スロット番号付き cut を syntax-rules で書く - 主題のない日記

だが、 R5RS の範囲内では書けなかった。

今回は R5RS の範囲内で書いた。 つもりなのだが…。 Gauche を含むいくつかの R5RS 処理系ではエラーとなった。 詳細は後述する。

(define-syntax %%%cutn
  (syntax-rules ()
    ((_ args () slots)
     (lambda slots args))
    ((_ (r ...) (a0 a1 ...) (slots ...))
     (letrec-syntax ((ex (syntax-rules (slots ... <...>)
                        ((_ slots)
                         (%%%cutn (r ... slots) (a1 ...) (slots ...)))
                        ...
                        ((_ <...>)
                         (rx (r ...) (slots ...) a1 ...))
                        ((_ x)
                         (%%%cutn (r ... a0) (a1 ...) (slots ...)))))
                  (rx (syntax-rules ()
                        ((_ args (slots ...))
                         (lambda (slots ... . <...>)(apply r ... <...>))
                        ))))
       (ex a0)))))

(define-syntax %%cutn
  (syntax-rules ()
    ((_ args _1 slots _2 ())
     (%%%cutn () args slots))
    ((_ args (r1 ...) (r2 ...) (u ...) (s ss ...))
     (let-syntax ((ex (syntax-rules (u ...)
                        ((_ u)
                         (%%cutn args (r1 ... s) (r1 ... s) (u ...) (ss ...)))
                        ...
                        ((_ x)
                         (%%cutn args (r1 ... s) (r2 ...) (u ...) (ss ...))))))
       (ex s)))))

(define-syntax %cutn
  (syntax-rules ()
    ((_ args r slots)
     (%%cutn args () () r slots))
    ((_ args (r ...) (slots ...) a0 a1 ...)
     (let-syntax ((ex (syntax-rules (slots ...)
                        ((_ slots)
                         (%cutn args (r ... slots) (slots ...) a1 ...))
                        ...
                        ((_ _)
                         (%cutn args (r ...) (slots ...) a1 ...))
                        )))
       (ex a0)))))

(define-syntax cutn
  (syntax-rules ()
    ((_ args ...)
     (%cutn (args ...) () (<0> <1> <2> <3> <4> <5> <6> <7> <8> <9>) args ...))))

これで問題になるのはマクロテンプレートに現われる ellipsis のようだ。 問題を再現する小さな例を書いてみた。

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

(hoge 1 2 3)

これが許されるべきなのかどうか R5RS を読んでもよくわからない。

Document ID: 7841b2535bdfb990d918947333337b0a