1

在 Guile 中,我正在努力学习define-syntaxsyntax-rules. 我的印象是方案宏不评估他们的论点,但我的似乎正在这样做:

(define-syntax foo
    (syntax-rules ()
        ((foo word)
            (if (eqv? word 'bar) (begin (write "Caller said BAR!") (newline)))
            )))

如果我用 调用它(foo bar),我会收到错误消息

未绑定变量:bar

而如果我用 调用它(foo 'bar),我会得到预期的

“来电者说BAR!”

这看起来好像在应用宏之前对参数进行了评估。

4

1 回答 1

1

您应该首先尝试查看宏扩展是什么:

scheme@(guile-user)> (use-modules (language tree-il))
scheme@(guile-user)> (tree-il->scheme (macroexpand '(foo bar)))

为清楚起见,缩进编辑

(if ((@@ (#{ g184}#) eqv?) bar (quote bar))
    (begin ((@@ (#{ g184}#) write) "Caller said BAR!")
       ((@@ (#{ g184}#) newline))))

所以(foo bar)转化为(去掉@@s后):

(if (eqv? bar (quote bar))
    (begin (write "Caller said BAR!")
       (newline)))

在评估发生之前。现在这个错误有意义不是吗?

现在如果你引用word参数会发生什么?看看这是如何扩展的:

(define-syntax foo
  (syntax-rules ()
    ((foo word)
     (if (eqv? 'word 'bar) (begin (write "Caller said BAR!") (newline))))))
于 2021-09-28T04:41:02.680 回答