【发布时间】:2011-08-18 03:08:24
【问题描述】:
我正在尝试学习 Lisp,但我被这个例子卡住了(你可以在 Paul Graham 的“ANSI Common Lisp”中找到它,第 170 页):
(defmacro in (obj &rest choices)
(let ((insym (gensym)))
`(let ((,insym ,obj))
(or ,@(mapcar #'(lambda (c) `(eql ,insym ,c))
choices)))))
格雷厄姆接着说:
第二个宏 [...]
in如果它的第一个参数是eql则返回true到任何其他参数。我们可以写成这样的表达式:
(in (car expr) '+ '- '*)
否则我们将不得不写成
(let ((op (car expr)))
(or (eql op '+)
(eql op '-)
(eql op '*)))
当我编写的以下函数似乎表现相同时,为什么要编写宏?
(defun in-func (obj &rest choices)
(dolist (x choices)
(if (eql obj x)
(return t))))
我不明白我是否遗漏了什么,或者在这种情况下,in-func 等同于 in。
【问题讨论】:
-
您缺少的一件事是
dolist也是一个宏,尽管它更复杂。 -
geekosaur: 是的,
dolist是一个宏,但总的来说,如果您可以对函数执行相同的操作,那么避免编写 new 宏是有好处的。由于宏不遵循通常的评估规则,宏会使未来的读者更难编写代码。 (当然,在这种情况下,in正是因此而被定义为宏。) -
@Eli 是的,这正是我所关心的。
标签: function macros lisp common-lisp