基本上,我什么时候应该使用Emacs Lisp的function
程序?我还没有发现其中有行为上的差异,如果你函数作为参数传递的任何实例'like-this
或#'like-this
.事实上,如果我评估(eq 'goto-char #'goto-char)
它返回t
.
我遇到的Emacs Lisp代码很少使用function
/ #'
; 作者只是quote
/ '
一切.
例:(add-hook 'emacs-lisp-hook 'turn-on-eldoc-mode)
但是,我可以找到一些反例.这是Emacs 24.3源代码中的一个electric.el
:
(add-hook 'post-self-insert-hook #'electric-indent-post-self-insert-function 'append)
它只是一个Lisp-2风格大会吗?
它与字节编译有关吗?
这对图书馆作家来说是否有意义?比如,如果您打算在大量环境和Emacs版本下运行您的代码?(推论是如果你只是"dotfile-tinkering"那么你不需要担心这一切.)
什么时候应该引用lambda表达式?我什么时候可以不加引号?
例如,(do-something '(lambda …
与 (do-something (lambda …
在早期版本的Emacs中是否有一些限制,这些限制引起了elisp的这些方面?就像,我可以忽略大多之间的区别'
和#'
,只要我使用一个版本的Emacs超过最近X?
Stefan.. 33
function
(aka #'
)用于引用函数,而quote
(aka '
)用于引用数据.现在,在Emacs-Lisp中,一个符号,其功能单元是一个函数本身就是一个函数,所以#'symbol
与'symbol
实践中的相同(因为意图不同,第一个明确表示不仅仅是在谈论符号"符号") "但关于名为"symbol"的函数.
差异不仅仅是风格的地方是引用lambdas时:'(lambda ...)
是一个表达式,它的计算结果是第一个元素是符号的列表lambda
.你被允许应用car
和cdr
它一样的东西,但你不应该把它称为它是一个函数(虽然在实践中它往往工作得很好).相反#'(lambda ...)
(可以写成(lambda ...)
)是一个评估函数的表达式.这意味着你不能应用car
它,但字节编译器可以查看内部#'(lambda ...)
,在其中执行宏扩展,警告你,如果它找到的东西看起来不是犹太洁食等等; 对于词法绑定,它甚至必须查看内部才能找到该函数所引用的自由变量.
function
(aka #'
)用于引用函数,而quote
(aka '
)用于引用数据.现在,在Emacs-Lisp中,一个符号,其功能单元是一个函数本身就是一个函数,所以#'symbol
与'symbol
实践中的相同(因为意图不同,第一个明确表示不仅仅是在谈论符号"符号") "但关于名为"symbol"的函数.
差异不仅仅是风格的地方是引用lambdas时:'(lambda ...)
是一个表达式,它的计算结果是第一个元素是符号的列表lambda
.你被允许应用car
和cdr
它一样的东西,但你不应该把它称为它是一个函数(虽然在实践中它往往工作得很好).相反#'(lambda ...)
(可以写成(lambda ...)
)是一个评估函数的表达式.这意味着你不能应用car
它,但字节编译器可以查看内部#'(lambda ...)
,在其中执行宏扩展,警告你,如果它找到的东西看起来不是犹太洁食等等; 对于词法绑定,它甚至必须查看内部才能找到该函数所引用的自由变量.
在elisp #'
中(实际上)纯粹是关于字节编译(编辑:因为Emacs 24,也是词法闭包); 但你也可能永远不需要使用它.
#'...
是简单的,(function ...)
它只是一个变体'...
/ (quote ...)
也暗示字节编译器它可以将引用的形式编译为函数.
然而,在现代Emacs(IIRC并非总是如此),(lambda ...)
相当于#'(lambda ...)
,所以我相信你很少(如果有的话)需要写#'
.
你也很少想要使用'(lambda ...)
,因为Stefan已经详细说明了(但'symbol
很好).
这在下面的手册中有所介绍C-hig (elisp) Anonymous Functions
RET(尽管最后一段示例代码中似乎有错误,因为它与前面的示例相同(在Emacs 24.3.1中)).
(斯特凡的回答是确定的,但我会把这个保留在这里,因为它有希望补充它.)
除了引用(lambda ...)
表单时的差异,最近(从Emacs 24.4开始)对bytecomp.el进行了更改,以便在使用#'symbol
表单时生成警告,但不知道函数在结尾时是否已定义.汇编.
因此,使用函数引用#'symbol
语法而不是'symbol
语法编写所有函数符号是有些优选的,因为它允许字节编译器检查您是否使用了实际定义的函数名.
以前(Emacs 24.3及更早版本),虽然字节编译器会在您调用函数时发出警告,(no-such-function ...)
并且未定义或从另一个文件中干净地导入,但类似的情况(mapcar #'no-such-function ...)
只会产生运行时错误而没有编译时警告.
这一变化意味着这两种情况现在都会产生编译时警告; 但是,如果您在(mapcar 'no-such-function ...)
不使用函数引用的情况下使用,则再次不会生成编译时警告.所以#'
可以帮助早期发现错误(可能是错别字).
函数引用也有助于自上而下的编程风格,因为字节编译器将列出您尚未实现的函数(但会遗漏用正常引用指定的函数).