2

単純なネストされたマクロを作成しようとしています。私の Scheme 実装では動作しますが、Guile と Racket では動作しません。

(define-syntax foo
  (syntax-rules (:c)
    ((_ x ...)
     (let-syntax ((bar (syntax-rules ::: (:c)
                         ((_ x)
                          (print x))
                         ((_ a b :::)
                          (begin
                            (display a)
                            (display " ")
                            (bar b :::))))))
       (bar x ...)))))
  • ガイルスロー:

構文: 省略記号がありません

  • ラケット投げ:

テンプレートにパターン変数の省略記号がありません

私もGambitで実行しようとしましたが、それはただスローされます:

バインドされていない変数: define-syntax

基本的なスキームを使用するには、ライブラリを使用する必要があると思います。

Checken スキームでは、省略記号を更新した後:

(define-syntax foo
  (syntax-rules (:c)
    ((_ x ...)
     (let-syntax ((bar (syntax-rules <:::> (:c)
                         ((_ x)
                          (print x))
                         ((_ a b <:::>)
                          (begin
                            (display a)
                            (display " ")
                            (bar b <:::>))))))
       (bar x ...)))))

スロー:

テンプレートの寸法エラー (楕円が少なすぎますか?): x

このマクロの何が問題になっていますか? エラーが発生するのはなぜですか?

編集

このパターンは有効ではないようです:

(_ x ...)

しかし、これは

(_ x y ...)

これはどこかに指定されていますか?最初の構文が有効でないのはなぜですか?

念のために言っておきますが、このコードはコンパイルできますが、なぜ最初のコードはコンパイルできないのでしょうか?

(define-syntax foo
  (syntax-rules ()
    ((_ x y ...)
     (let-syntax ((bar (syntax-rules <:::> ()
                         ((_ x)
                          (print x))
                         ((_ a b <:::>)
                          (begin
                            (display a)
                            (display " ")
                            (bar b <:::>))))))
       (bar x y ...)))))

fooしかし、マクロを使おうとするとうまくいきません。それはスローします:

非バインド変数: bar

使用時もletrec-syntax

4

3 に答える 3

1

x問題は、外側のマクロで省略記号が続いていることです。これは、生成されるテンプレートにも省略記号が続く必要があることを意味しますがx、そうではありません。内部マクロの名前を変更すると、x期待yどおりに機能するはずです。

つまり、ここで行っていることは次と同等です。

(define-syntax foo
  (syntax-rules ()
    ((_ x ...)
     (display x))))

どちらも許されません。xパターンに with ellipsis がある場合はx、それに続くテンプレートで使用するときにそれらの省略記号も使用する必要があります。

作成した場合に機能する理由(x y ...)は、y(およびその省略記号の残り)がテンプレートによってまったく消費されないためです。

于 2021-08-12T05:04:38.330 に答える