符号和名称是否不同? Paul Graham的 On Lisp 专注于常见的口齿不清,有一些似乎暗示的讨论,例如。
由于lambda表达式也是函数的名称,因此它们也可以首先出现在函数调用中:
((lambda(x)(* x 2)3)
6
这使得听起来像符号是名称但名称不是符号。但我不明白什么样的Lisp"对象"符号是/可能是。
这也来自尖锐引用(#'
)运算符v。symbol-function
上的my question here。我怀疑这些不同的唯一原因是因为并非所有的名字都是符号,但我还没有足够的背景来理解这些答案(因此这个问题)。
我还要求在elisp诉普通lisp中澄清。我假设这与词汇形式有关,直到版本24(我认为24.1)才在elisp中引入。
答案 0 :(得分:5)
Lambda表达式不是函数的名称。只是在Common Lisp中允许((lambda (...) ...) ...)
,因为它在标准中被定义为合法语法。
Common Lisp中唯一允许的函数名称是(setf symbol)
等符号和列表。
例如,可以写
(defun (setf foo) (...) ...)
此处(setf foo)
是函数名称。
Common Lisp中不存在其他函数名,只有符号和(setf symbol
)名称。
Common Lisp Hyperspec词汇表:Function Name。
function name n。 1.(在环境中)符号或列表(setf symbol)这是该环境中函数的名称。 2. A 符号或列表(setf符号)。
注意:1984年的Common Lisp版本(在CLtL1中发布)只有符号作为函数名称。因此,没有定义函数名称的想法。从符号中检索函数的函数称为SYMBOL-FUNCTION
。 1989年,ANSI CL标准化小组决定将setf列表添加为函数名称。它还引入了函数FDEFINITION
,它类似于SYMBOL-FUNCTION
,但除了符号之外还接受其他函数名称。见这里:Issue FUNCTION-NAME。
答案 1 :(得分:4)
我认为Rainer's answer是正确的,但由于问题出现在对my answer到another question的评论中,我将包括(更新)我的回复来自that comment 的
符号是实际对象。您可以检查它,可以使用 make-symbol 等创建它们。重要的是,符号是Common Lisp中源代码的主要组件之一。函数名称,特别是在此问题出现的上下文中(函数特殊运算符的参数)是(setf symbol )<的形式的符号或列表/ strong>根据词汇表条目:
function name n。 1.(在环境中)符号或列表(setf符号),它是该环境中函数的名称。 2. A 符号或列表(setf符号)。
功能是一个不评估其参数的特殊运算符,因此传递符号或 setf 列表意味着:
(function car)
(function (setf car))
而不是:
(function 'car)
(function '(setf car))
现在,词汇变量,例如(let((x 42))x)中的 x ,虽然源代码中的符号表示,但实际上并不存在在运行时与符号有任何连接。 (let((x 42))x)的编译版本不需要知道关于符号 x 的任何信息。直觉上,这是有道理的,因为我们希望代码(let((y 42))y)能够编译成相同的东西。但是,当变量是特殊变量时,与符号有连接。差异最明显的是:
(let ((x 42))
(symbol-value x))
;=> NIL
(let ((x 42))
(declare (special x)) ; or (defparameter x ...) or (defvar x ...) earlier
(symbol-value x))
;=> 42
我们期望词法范围的函数也是如此,例如,以下代码会导致错误,因为运行时符号 x 与本地函数之间没有连接:
(flet ((x () 42))
(symbol-function 'x)) ; ERROR, no function value for symbol x
但即便如此,我们仍然可以这样做:
(flet ((x () 42))
(function x))
这是因为功能是特殊操作符,可以访问发生的环境。这意味着(因为它很特殊,并且实现使其工作)它可以知道 x 在此定义为函数。现在可能有趣的是,由于 flet 和标签被定义为采用函数名称,您可以这样做:
(flet (((setf kar) (value kons)
...))
...)