Common Lisp 中自定义宏 defmacro 的学习体会(一)
很多LISP高人都说,宏是LISP中最强的表达形式,你可以用它来构造新的语法,定义自己的特定领域语言。
本文记录一些学习中的粗浅心得,看看是否能通过表达--写出来的方式让自己理解得更深入。
宏的基本框架:
(defmacro name (parameter*)
"可选的对该宏的说明描述文档字符串"
body-form*)
这么看可能不是很直观,举个实际的例子:
(defmacro when (condition &rest body)
`(if (not ,condition) (prong ,@body)))
其中的对应关系如下:
name == when
(parameter*) == (condition &rest body)
body-form* == `(if (not ,condition) (prong ,@body))
这个例子里没有可选的说明字符串
这个新定义的宏 when 的使用方式如下:
;;格式
(when (判断条件)
(语句1)
(语句2))
;;例子
(when (= x 10)
(+ x 1)
(* x 2))
从宏定义的格式来看,定义宏中的形式体必须使用反引号“`”,表示对该形式体不求值,但是要对新宏的参数求值;
新宏的参数有两类,一个是新宏的形参,一个是新宏的形式体。
这两者的共同点就是都要通过逗号“,”来求值;
不同点有两处,一是形参用逗号直接求值,形式体则用逗号和@ 即 “,@” 去掉对形式体求值后所得到的表达式最外层列表的括号,将这个表达式嵌入到最外围列表的最后面;二是形参要做一系列处理,而形式体则直接求值嵌入,不做任何变化,这是因为这个形式体本来就是新宏的处理语句,定义宏只需要照搬即可,不需要也不应该做其他变化。
阅读宏定义代码或者自己去编写宏定义时,只要能牢牢把握住上面提到的差异,应该比较容易理解那些或简单、或复杂的宏代码了。