vrd*_*rde 8 lisp macros function common-lisp
我正在尝试学习Lisp,但是我被这个例子困住了(你可以在"ANSI Common Lisp"上找到它,Paul Graham,第170页):
(defmacro in (obj &rest choices)
(let ((insym (gensym)))
`(let ((,insym ,obj))
(or ,@(mapcar #'(lambda (c) `(eql ,insym ,c))
choices)))))
Run Code Online (Sandbox Code Playgroud)
格雷厄姆然后说:
如果第一个参数的第一个参数是任何其他参数,则
in返回第二个宏[...] .我们可以写成的表达式:trueeql
(in (car expr) '+ '- '*)
Run Code Online (Sandbox Code Playgroud)
否则我们不得不写作
(let ((op (car expr)))
(or (eql op '+)
(eql op '-)
(eql op '*)))
Run Code Online (Sandbox Code Playgroud)
当我写的下面的函数看起来行为方式相同时,为什么我应该写一个宏?
(defun in-func (obj &rest choices)
(dolist (x choices)
(if (eql obj x)
(return t))))
Run Code Online (Sandbox Code Playgroud)
我不明白我是否遗漏了某些东西,或者在这种情况下,in-func相当于in.
使用宏与函数的区别在于是否始终评估所有选项.
扩展in宏按顺序评估选择.如果它到达第一个参数的eql选项,它将返回一个true值,而不再评估任何表单.
相反,该in-func函数将在调用函数时评估所有选择.