我正在尝试编写模式匹配宏。我还没有走多远,但我已经很困惑了。我的测试代码如下
#!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
返回的parse-clauses
确实引用x
了 lambda 表达式中的参数。我不知道为什么。
这种细微的变化让我更加困惑。
#!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
,但是我在该范围之外使用了引用,所以我得到了一个错误。
我想我要说的是第二个示例表明词法上下文很重要,但在第一个示例中没有词法绑定,x
那么它为什么最终引用了不相关的绑定?
我希望这不会太混乱,欢迎任何解释。
我正在使用球拍 5.3.6。