为什么我的Guile Scheme自定义宏会对传入参数进行求值?
问题原因分析
- 你对Scheme宏「不对参数求值」的特性存在误解:该特性指宏展开阶段会将传入的参数表达式原封不动替换到宏模板的对应位置,不会预先计算参数的值,而非「替换后生成的代码在运行阶段也不会对对应位置的表达式求值」。
- 你当前的宏调用
(foo bar)展开后生成的代码如下:
(if (eqv? bar 'bar) (begin (write "Caller said BAR!") (newline)))
运行这段代码时,解释器会尝试对bar标识符求值获取变量值,而你没有定义名为bar的变量,自然会抛出Unbound variable: bar错误。
- 调用
(foo 'bar)时展开后的代码为:
(if (eqv? 'bar 'bar) (begin (write "Caller said BAR!") (newline)))
'bar是符号字面量,求值结果就是自身,所以可以正常运行得到预期结果。
需求适配方案
如果你希望直接调用(foo bar)就能正常匹配,不需要手动加引号,只需要修改宏模板,将传入的标识符在模板中显式标记为字面量即可:
(define-syntax foo (syntax-rules () ((foo word) (if (eqv? 'word 'bar) (begin (write "Caller said BAR!") (newline))) )))
修改后宏调用(foo bar)展开后会直接将word替换为bar生成(eqv? 'bar 'bar)的判断,不需要额外定义bar变量就能正常运行。
内容的提问来源于stack exchange,提问作者beguiler
相关产品推荐
相关产品推荐

