Racket宏语法与方括号的匹配

3

由于某些原因,运行以下代码行:

(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后面的文字只是一个单一的参数,它怎么能匹配两个模式变量呢?
2个回答

4
读者将'("A")转化为(quote ("A"))。这意味着(TEST '("A"))会转化为(TEST (quote ("A")))
这解释了为什么模式(TEST [<table> <name>])匹配。子模式<table>匹配quote<name>匹配("A")

3
请注意,'x 只是 (quote x) 的读取器缩写。因此,当您编写 (TEST '("A")) 时,它与编写 (TEST (quote ("A"))) 完全相同。因此,它匹配第一个模式,其中 <table> 绑定到 quote<name> 绑定到 ("A")
这可能有点令人困惑,但请记住,宏完全在编译时操作。因此,在传递给宏之前,'("A") 永远不会被评估为任何内容,而是直接传递。 syntax-rules 模式匹配结构根本不关心 quote 的特殊含义,它只匹配列表和对的语法结构,因此您得到了发现的行为。
根据您实际尝试做什么,有几种方法可以获得所需的行为。如果要针对运行时值进行模式匹配,请使用 match 而不是 syntax-rules。如果您确实需要宏,但希望更具体地匹配将匹配的内容类型,则可能需要使用 syntax-parse 而不是 syntax-rules。不过,如果没有更多信息,很难提供具体的建议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接