2

パターン マッチング マクロを作成しようとしています。あまり進んでいませんが、すでに混乱しています。私のテストコードは次のとおりです

#!r6rs

(import (for (rnrs base (6)) run expand)
        (for (rnrs syntax-case (6)) expand)
        (rnrs io simple (6)))

(define-syntax matcher
  (lambda (stx)

    (define (parse-clauses c)
      #'x)

    (syntax-case stx ()
      ((_ c ...)
       (with-syntax ((body (parse-clauses #'(c ...))))
         #'(lambda (x) body))))))

(write ((matcher) '(1 2 3))) (newline)

これを実行すると、出力が生成されます(1 2 3)

正直なところ、私はこのコードが失敗することを期待して書きました。parse-clausesから返された構文が未定義のシンボルを参照していると思いましたx。しかし、#'x返された fromはラムダ式parse-clausesのパラメーターを参照しているようです。x理由がわかりません。

このわずかな違いは、私をさらに混乱させます。

#!r6rs

(import (for (rnrs base (6)) run expand)
        (for (rnrs syntax-case (6)) expand)
        (rnrs io simple (6)))

(define-syntax matcher
  (lambda (stx)

    (define (parse-clauses c)
      (let ((x 1))
        #'x))

    (syntax-case stx ()
      ((_ c ...)
       (with-syntax ((body (parse-clauses #'(c ...))))
         #'(lambda (x) body))))))

(write ((matcher) '(1 2 3))) (newline)

これにより、エラーが発生しますx: identifier used out of context in: x。私が理解しているこのエラーxは でローカルにバインドされてparse-clausesいますが、そのスコープ外で参照を使用しているため、エラーが発生します。

私が言いたいのは、2 番目の例では字句コンテキストが重要であることを示しているが、最初の例では字句バインディングがないxため、無関係のバインディングを参照することになるのはなぜでしょうか?

あまり混乱していないことを願っています。説明は大歓迎です。

Racket 5.3.6 を使用しています。

4

1 に答える 1