看起来既Lisp中'和#'有什么区别?
(mapcar 'car '((foo bar) (foo1 bar1)))
和
(mapcar #'car '((foo bar) (foo1 bar1)))
工作一样。
而且我也知道'
的意思是(引号)和#'
的意思是(功能函数名)。
但是根本的区别是什么?为什么这两个都在以前的mapcar
工作?
看起来既Lisp中'和#'有什么区别?
(mapcar 'car '((foo bar) (foo1 bar1)))
和
(mapcar #'car '((foo bar) (foo1 bar1)))
工作一样。
而且我也知道'
的意思是(引号)和#'
的意思是(功能函数名)。
但是根本的区别是什么?为什么这两个都在以前的mapcar
工作?
'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)))
这里(函数foo)或它的速记符号#'富指的是词法本地函数FOO。
还要注意的是,在
(funcall #'foo ...)
与
(funcall 'foo ...)
后来可以做一个更间接的,因为它需要查找从符号的功能,同时#'富表示功能直。
摘要:
如果符号具有的功能绑定,调用函数通过符号的作品。
尝试将一个匿名函数(lambda)传递给您的mapcar
,您会发现#'
是必需的,因为引用本身需要绑定到函数的符号,但符号不存在于un-命名函数:
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))>.
VS:
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)