我在Common Lisp中使用mapcar,我看过使用#'和'在+前面,但他们似乎都做同样的事情。使用哪个是否重要?
CL-USER> (mapcar '+ '(1 2) '(2 3))
(3 5)
CL-USER> (mapcar #'+ '(1 2) '(2 3))
(3 5)
答案 0 :(得分:2)
它们通常可以互换,但不是一回事。 mapcar
使用函数指示符 - 指定symbol-function
的符号或指定自身的函数 - 将强制转换为函数对象。 #'foo
是一个扩展为(function foo)
的读取器宏,它通过在词法环境中查找foo
的功能值(即最里面的flet
,{}来返回一个函数对象。 {1}},或全局函数定义。因此,不需要做任何强迫它。但是,如果使用带labels
的带引号的符号,则会使用mapcar
强制转换为函数,这不适用于非全局函数定义,因为不涉及symbol-function
个符号在这种情况下。例如:
fboundp
此外,when exactly the coercion happens, is implementation dependent,这会对自我或mutualy重新定义代码产生影响。
一般来说,使用CL-USER> (flet ((frob (x) (1+ x)))
(mapcar #'frob '(1 2 3)))
(2 3 4)
CL-USER> (flet ((frob (x) (1+ x)))
(mapcar 'frob '(1 2 3)))
; Evaluation aborted on #<CCL::UNDEFINED-FUNCTION-CALL #x18AB7F1E>.
似乎现在更受欢迎,可能是因为感觉更加一致 - 使用#'
想要传递函数的地方是一个简单的规则。我很少看到带引号的符号与CL中的函数指示符一起使用。然而,在其他方言中,尤其是较老的或动态范围的方言,如Emacs Lisp,将引用的符号传递给这些函数是很常见的。