为什么我的(诡计)计划宏评估其论点?
Why is my (guile) scheme macro evaluating its argument?
在 Guile 中,我正在努力学习 define-syntax
和 syntax-rules
。我的印象是方案宏不会评估他们的论点,但我的似乎正在这样做:
(define-syntax foo
(syntax-rules ()
((foo word)
(if (eqv? word 'bar) (begin (write "Caller said BAR!") (newline)))
)))
如果我用 (foo bar)
调用它,我会收到错误消息
Unbound variable: bar
而如果我用 (foo 'bar)
调用它,我会得到预期的
"Caller said BAR!"
这使得参数看起来好像在应用宏之前得到评估。
你应该先看看宏展开是什么:
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))))))
在 Guile 中,我正在努力学习 define-syntax
和 syntax-rules
。我的印象是方案宏不会评估他们的论点,但我的似乎正在这样做:
(define-syntax foo
(syntax-rules ()
((foo word)
(if (eqv? word 'bar) (begin (write "Caller said BAR!") (newline)))
)))
如果我用 (foo bar)
调用它,我会收到错误消息
Unbound variable: bar
而如果我用 (foo 'bar)
调用它,我会得到预期的
"Caller said BAR!"
这使得参数看起来好像在应用宏之前得到评估。
你应该先看看宏展开是什么:
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))))))