13

似乎两者

(mapcar 'car '((foo bar) (foo1 bar1))) 

(mapcar #'car '((foo bar) (foo1 bar1)))

一样工作。

而且我也知道'手段(引号)和#'手段(功能函数名)。

但根本的区别是什么?为什么这两个都在以前工作mapcar

4

3 回答 3

15
'foo

计算为符号 FOO。

#'foo

计算为绑定到名称 FOO 的函数。

在 Lisp 中,当符号 FOO 具有函数绑定时,可以将符号作为函数调用。这里的 CAR 是一个具有函数绑定的符号。

但这不起作用:

(flet ((foo (a) (+ a 42)))
  (mapcar 'foo '(1 2 3 4 5)))

那是因为 FOO 作为一个符号不访问本地词法函数,当foo不在别处定义函数时,Lisp 系统会报错。

我们需要写:

(flet ((foo (a) (+ a 42)))
  (mapcar #'foo '(1 2 3 4 5)))

这里 (function foo) 或其简写符号 #'foo 指的是词法局部函数 FOO。

另请注意,在

(funcall #'foo ...)

对比

(funcall 'foo ...)

后者可能会做更多的间接,因为它需要从符号中查找函数,而#'foo 直接表示函数。

摘要

如果符号具有函数绑定,则通过符号调用函数有效。

于 2011-02-05T10:15:37.960 回答
9

为什么这两个都在以前的地图车中工作?

mapcar的文档说:

如果 function 是一个符号,则它被强制转换为一个函数,就像通过symbol-function一样。

于 2011-02-05T10:15:04.270 回答
2

尝试将匿名函数(lambda)传递给您mapcar,您会发现这#'是必需的,因为引号本身需要一个绑定到函数的符号,但该符号在未命名的函数中不存在:

CL-USER> (mapcar '(lambda (x) (format t "it is ~d" x)) (list 3 5 7))
; Evaluation aborted on #<TYPE-ERROR expected-type: (OR FUNCTION SYMBOL)
             datum: (LAMBDA (X) (FORMAT T "it is ~d" X))>.

与:

CL-USER> (mapcar #'(lambda (x) (format t "it is ~d" x)) (list 3 5 7))
it is 3it is 5it is 7
(NIL NIL NIL)
于 2013-11-03T06:54:57.883 回答