为什么在emacs-lisp中的函数参数之前使用#'?

sea*_*mcl 16 lisp emacs elisp common-lisp

我熟悉Emacs Lisp,但不熟悉Common(或任何其他)Lisp.一些Lisp程序员建议(例如,emacs的一个基本函数),它可以#'在Lisp代码中的函数参数前使用.例如:

(mapc #'my-fun '(1 2 3))
Run Code Online (Sandbox Code Playgroud)

在Emacs Lisp中,我相信这相当于

(mapc 'my-fun '(1 2 3))
Run Code Online (Sandbox Code Playgroud)

从elisp手册,第12.7节.

读取语法#'是使用的简写function.以下表格都是等效的:

 (lambda (x) (* x x))
 (function (lambda (x) (* x x)))
 #'(lambda (x) (* x x))
Run Code Online (Sandbox Code Playgroud)

和帮助 function

功能是一种特殊的形式eval.c.

(function ARG)
Run Code Online (Sandbox Code Playgroud)

喜欢quote,但对于作为功能的对象更喜欢.在字节编译中,function导致其参数被编译.quote 不能那样做.

所以这似乎是一个潜在的优化,但不再是.此外,来自ML/Haskell背景,以不同于任何其他数据的方式处理函数似乎很奇怪.

题:

你是否同意#'应该在emacs-lisp函数参数中使用?(简要说明Common Lisp中为什么需要它们也会很棒.)

笔记:

我认为当#'省略(值与函数)时它可能会读取不同的单元格.但这似乎是错误的,因为文档function没有说明抓住功能单元格.这是通过使用来实现的symbol-function.

相关问题是

但他们似乎认为这#'是不必要的,至少在lambdas中是这样.

Sva*_*nte 18

引用字符#'foo与中的字符无关'foo.

#'foo被替换的读取时间(function foo).当被编译并执行,它通过查找功能定义名为foo(通过defun,flet,labels或类似).

'foo被替换的读取时间(quote foo).当编译和执行它时,它只是被符号替换foo.

Funcallapply(因此通常高阶函数)取功能指示符作为参数.甲功能指示符可以是一个函数或符号命名的函数,因此这两个#'foo'foo是功能指示符.

因此,形式'foo#'foo乍一看似乎可以互换.但是,实际函数的查找是在不同的时间完成的 - 查找#'foo它被调用的位置,而命名的函数'foo只有在最终应用时才会被查找.

如果多次使用函数指示符,那么只进行一次查找或者甚至只是在编译时进行查找会更有效.这可能是一个非常大的节省时间,并转换为编辑器中更流畅的用户体验.

  • 特别是在Emacs Lisp中,我确实认为`'foo`和`#'foo`是等价的,但使用后者仍然是一个信号,你是在一个函数定义之后. (4认同)