日常我们写lisp程序的时候一些过程可以通过复合表达式定义,通常情况下可以用lambda,lambda表达式格式如下:
(lambda (args) exp)
然后如何让这个过程复用呢,这个时候我们起个名字引用它,一般可以用 define 表达式,格式如下:
(define symbol exp)
然后我们以写println这个过程(函数为例),我们可以将 display、 newline 过程组合成一个新的过程(函数),可以这样写:
(define println (lambda (x) (
(display x)
(newline))))
然后输入
(println 'hello-world')
=> 'hello-world'
我们能不能简化带有名称的函数编写呢?,当然是可以的,这里我们通过定义一个宏函数,它长这样
(define-macro defun (lambda (name args . body) (
`(
define ,name (lambda ,args ,@body)
)
)))
还是以println 函数为例,那么怎么定义呢?可以这样:
(defun println (x) (
(display x)
(newline)
))
然后输入
(println 'hello-world')
=> 'hello-world'
总结
通过宏我们可以扩充我们使用语言的语法结构,使一些语法变得更简单,但它无疑也是一把双刃剑,它会让我们使用的语言成为另一种语言,对定义者也许是友好的,但对使用者无疑增加了许多心智负担,如何权衡利弊的去使用宏不是一个一蹴而就的过程。