一个符号可以作为函数的名称。当符号的 函数单元(function cell)(see 符号的组成)中存放了一个函数对象(例如 lambda 表达式)时,就会形成这种情况。此时,符号本身就成为一个合法、可调用的函数,等价于其函数单元中的函数对象。
函数单元里的内容也被称为该符号的 函数定义(function definition)。使用符号的函数定义来代替符号本身的过程,称为 符号函数间接解析(symbol function indirection);参见 符号函数间接引用。 如果你没有为某个符号设置函数定义,它的函数单元就被称为 无效(void),该符号也就不能用作函数。
在实际使用中,几乎所有函数都有名称,并且通过名称来引用。你可以通过定义一个 lambda 表达式并将其放入函数单元来创建一个命名的 Lisp 函数(see 访问函数单元内容)。不过,更常见的做法是使用下一节介绍的 defun 宏。
See 定义函数.
我们为函数命名,是因为在 Lisp 表达式中通过名称引用函数会很方便。此外,命名函数可以轻松地引用自身 —— 即可以是递归的。更进一步说,原语只能通过名称以文本形式引用,因为原语函数对象(see 原语函数类型)没有可读语法。
一个函数不必拥有唯一的名称。一个给定的函数对象 通常 只出现在一个符号的函数单元中,但这只是一种约定。使用 fset 可以很容易地将它存入多个符号,这样每个符号都成为同一个函数的有效名称。
注意:用作函数名的符号,也可以同时用作变量;符号的这两种用途是相互独立、互不冲突的。(这一点在某些 Lisp 方言中并不成立,比如 Scheme。)
按照约定,如果一个函数的符号由 ‘--’ 分隔的两部分组成,说明该函数是内部使用的,且第一部分对应定义该函数的文件名。例如,名为 vc-git--rev-parse 的函数,就是定义在 vc-git.el 中的内部函数。用 C 语言编写的内部函数,名称以 ‘-internal’ 结尾,例如 bury-buffer-internal。2018 年之前提交的 Emacs 代码可能遵循其他内部命名约定,这些约定正在逐步淘汰。