Lisp中'和#'有什么区别?

Tho*_*son 13 lisp quote

似乎两者都有

(mapcar 'car '((foo bar) (foo1 bar1))) 
Run Code Online (Sandbox Code Playgroud)

(mapcar #'car '((foo bar) (foo1 bar1)))
Run Code Online (Sandbox Code Playgroud)

同样的工作.

我也知道'手段(引用符号)和#'手段(功能函数名称).

但潜在的差异是什么?为什么这两个都在以前工作mapcar

Rai*_*wig 14

'foo
Run Code Online (Sandbox Code Playgroud)

评估符号FOO.

#'foo
Run Code Online (Sandbox Code Playgroud)

计算绑定到名称FOO的函数.

在Lisp中,当符号FOO具有函数绑定时,可以将符号称为函数.CAR是一个具有功能绑定的符号.

但这不起作用:

(flet ((foo (a) (+ a 42)))
  (mapcar 'foo '(1 2 3 4 5)))
Run Code Online (Sandbox Code Playgroud)

这是因为作为符号的FOO不能访问本地词法函数,并且当foo不是其他地方定义的函数时,Lisp系统会抱怨.

我们需要写:

(flet ((foo (a) (+ a 42)))
  (mapcar #'foo '(1 2 3 4 5)))
Run Code Online (Sandbox Code Playgroud)

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

另请注意

(funcall #'foo ...)
Run Code Online (Sandbox Code Playgroud)

(funcall 'foo ...)
Run Code Online (Sandbox Code Playgroud)

后者可能会再做一次间接,因为它需要从符号中查找函数,而#'foo直接表示函数.

摘要:

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


Ken*_*Ken 9

为什么这两个都在以前的mapcar中工作?

mapcar的文档说:

如果function是一个符号,它就像一个符号函数一样被强制转换为函数.