Macros 规范匹配letrec实现是如何工作的?
我目前正在将几乎所有Scheme实现都使用的方法移植到另一个Lisp 我在Macros 规范匹配letrec实现是如何工作的?,macros,pattern-matching,scheme,metaprogramming,Macros,Pattern Matching,Scheme,Metaprogramming,我目前正在将几乎所有Scheme实现都使用的方法移植到另一个Lisp 我在match-letrec中遇到了一堵墙。在中,定义如下: (定义语法匹配let) (语法规则() ((((帕特解释))正文) (匹配表达式(零件正文))) (((pat expr)…正文) (匹配(列表expr…((pat….body))) (uuu.rest) (匹配名为let loop().rest)) )) (定义语法匹配letrec (语法规则() ((vars.body)(匹配letrec helper()var
match-letrec
中遇到了一堵墙。在中,定义如下:
(定义语法匹配let)
(语法规则()
((((帕特解释))正文)
(匹配表达式(零件正文)))
(((pat expr)…正文)
(匹配(列表expr…((pat….body)))
(uuu.rest)
(匹配名为let loop().rest))
))
(定义语法匹配letrec
(语法规则()
((vars.body)(匹配letrec helper()vars.body)))
(定义语法匹配letrec帮助程序
(语法规则()
(((pat expr var)…)正文)
(letrec((var expr)…)
(匹配let((帕特变量)…)
(见正文)
(v…)身体)
(匹配letrec辅助对象(v…(pat expr tmp))静止体)
))
下面是一个使用时的外观示例(Guile 1.8):
我很难理解这到底是怎么回事。当我用手将其展开到匹配
时,我得到以下代码(带有由{g..}
指示的自动符号):
(letrec(#{g1}(列表1(lambda()(列表a x)))
(#{g2}(列表2(lambda()(列表xaЮЮЮ)))
(匹配(列表{g1}{g2})(((xy)(ab))(附加(y)(b)))
自动符号由match letrec helper
第二条规则中的tmp
替换生成。此扩展意味着lambda表达式在绑定x
和a
之前进行计算,因此无法捕获它们
有人能解释一下这个语法应该如何正确扩展吗?我遗漏了什么?你的例子
(match-letrec (((x y) (list 1 (lambda () (list a x))))
((a b) (list 2 (lambda () (list x a)))))
(append (y) (b))
=> (2 1 1 2)
缺少一个紧括号
修复后,会发生以下情况:
> (match-letrec (((x y) (list 1 (lambda () (list a x))))
((a b) (list 2 (lambda () (list x a)))))
(append (y) (b)))
. match: syntax error in pattern in: ((x y) (a b))
连火柴都不行
> (match-let (((x y) (list 1 2)))
x)
. match: syntax error in pattern in: (x y)
> (match-letrec (((list x y) (list 1 (lambda () (list a x))))
((list a b) (list 2 (lambda () (list x a)))))
(append (y) (b)))
. match: syntax error in pattern in: ((list x y) (list a b))
以下是修复方法:
(define-syntax match-let
(syntax-rules (list)
((_ ((pat expr)) . body)
(match expr (pat . body)))
((_ ((pat expr) ...) . body)
(match (list expr ...) ((pat ...) . body)))
((_ loop . rest)
(match-named-let loop () . rest))
))
现在您可以执行以下操作:
> (match-let (((list x y) (list 1 2)))
(list x y))
'(1 2)
letrec仍不工作
> (match-let (((x y) (list 1 2)))
x)
. match: syntax error in pattern in: (x y)
> (match-letrec (((list x y) (list 1 (lambda () (list a x))))
((list a b) (list 2 (lambda () (list x a)))))
(append (y) (b)))
. match: syntax error in pattern in: ((list x y) (list a b))
但这会让你更进一步,一旦你理解了这些变化,就可以用工作代码示例问一个新问题。这在Racket 7.4、Chicken 4.13或Guile 2.2.4中都不起作用。它看起来与你链接的实现完全不同。谢谢。我更新了这个问题,以澄清我引用了simpli在这个问题中,我对Alex Shinn的matcher进行了详细的解释,并添加了一个链接。我将构建最新的Guile并进行查看。