Common Lisp mapcar'vs#'

时间:2014-07-27 04:15:37

标签: common-lisp

我在Common Lisp中使用mapcar,我看过使用#'和'在+前面,但他们似乎都做同样的事情。使用哪个是否重要?

CL-USER> (mapcar '+ '(1 2) '(2 3))
(3 5)
CL-USER> (mapcar #'+ '(1 2) '(2 3))
(3 5)

1 个答案:

答案 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,将引用的符号传递给这些函数是很常见的。