Tsi*_*Hui 4 scheme common-lisp syntax-rules
我了解到在方案中定义一个小宏很容易syntax-rules。是否可以定义一个宏来返回一个可以在 Common Lisp 中syntax-rules读取的列表?defmacro
这可能会像这样工作:
(defmacro and (&rest rest)
(syntax-rules (rest) ()
((_) t)
((_ x) x
((_ x y) (if x (if y y nil) nil))
((_ x y ...) (if x (and y ...) nil))))
Run Code Online (Sandbox Code Playgroud)
Tim Bradshaw 的destructuring-match目的是使宏中的这种模式匹配变得容易:它是caseand的组合destructuring-bind,因此每个子句的键都具有解构 lambda 列表的语法。CL 还有其他几种模式匹配系统,但这个系统明确旨在编写宏:它不是通用的数据结构匹配工具,只是destructuring-bind.
它附带了一个名为 的小示例宏(本身是使用 编写的,destructuring-match并且扩展为使用的东西destructuring-match!)define-matching-macro,您可以在其中编写 的版本and,此处称为et。我认为以下两个宏是正确的,但我没有考虑太多。
(define-matching-macro et
"This is meant to be AND"
((_) 't)
((_ x) x)
((_ x . more ) `(if ,x (et ,@more) nil)))
Run Code Online (Sandbox Code Playgroud)
您也可以仅destructuring-match在普通defmacro宏中使用。在这里,我没有用来&whole获取整个表单,因此我们不必费心处理car表单的:
(defmacro et (&rest forms)
"This is also meant to be AND"
(destructuring-match forms
(() 't)
((x) x)
((x . more) `(if ,x (et ,@more) nil))))
Run Code Online (Sandbox Code Playgroud)
笔记:
destructuring-match与Scheme一样使用名称为"_"空白的符号,因此您不需要声明它们被忽略,它们都是彼此不同的,事实上您可能不会在子句正文中引用它们;但它根本不做Scheme的x ...事情,所以你只需要使用点式lambda列表或&rest任何你喜欢的东西;(if x x nil), 以及冗余(它只是x) 可能会计算x两次,这是不安全的。