出于某种原因,运行这行代码:
(TEST '("A"))
匹配语法定义:
(define-syntax TEST
(syntax-rules ()
[(TEST [<table> <name>])
(print "Should not be here")] ;This statement is executed
[(TEST <table>)
(print "Should be here")] ;This should be executed but is not
))
这怎么可能?这对我来说没有意义,因为TEST之后的文字只是一个参数。它如何匹配两个模式变量?
答案 0 :(得分:4)
读者将'("A")
变为(quote ("A"))
。这意味着
(TEST '("A"))
变为(TEST (quote ("A")))
。
这解释了模式(TEST [<table> <name>])
匹配的原因。子模式<table>
匹配quote
,<name>
匹配("A")
。
答案 1 :(得分:3)
请注意,'x
只是(quote x)
的读者缩写。因此,当您编写(TEST '("A"))
时,它与编写(TEST (quote ("A")))
完全相同。因此,它匹配第一个模式,其中<table>
绑定到quote
,<name>
绑定到("A")
。
这可能有点令人困惑,但请记住,宏完全在编译时运行。出于这个原因,'("A")
在传递给宏之前永远不会被评估为任何东西,它只是直接传递。 syntax-rules
模式匹配结构根本不关心quote
的特殊含义,它只是匹配列表和对的语法结构,因此您可以获得您发现的行为。 / p>
根据您实际要做的事情,有几种方法可以获得您可能想要的行为。如果要对运行时值进行模式匹配,请使用match
,而不是syntax-rules
。如果您真的想要一个宏,但想要更具体地说明匹配的内容,您可能希望使用syntax-parse
而不是syntax-rules
。但是,如果没有更多信息,很难给出具体的建议。