Lisp 符号和名称不同吗?

Lisp 符号和名称不同吗?,lisp,elisp,common-lisp,symbols,lexical-scope,Lisp,Elisp,Common Lisp,Symbols,Lexical Scope,符号和名称不同吗?保罗·格雷厄姆(Paul Graham)的《论Lisp》(OnLisp)侧重于常见的Lisp,其中有些讨论似乎暗示了这一点,例如 由于lambda表达式也是函数名,因此它们也可以出现在函数调用中的第一位: ((λ(x)(*x2)3) 六, 这听起来好像符号是名称,但名称不是符号。但我不明白Lisp“object”符号是/可能是什么类型的 这也是源于尖锐的引号(#“)操作符v.符号函数。我怀疑它们不同的唯一原因是,不是所有的名字都是符号,但我还没有足够的背景来理解这些答案(因此这

符号和名称不同吗?保罗·格雷厄姆(Paul Graham)的《论Lisp》(OnLisp)侧重于常见的Lisp,其中有些讨论似乎暗示了这一点,例如

由于lambda表达式也是函数名,因此它们也可以出现在函数调用中的第一位:
((λ(x)(*x2)3)
六,

这听起来好像符号是名称,但名称不是符号。但我不明白Lisp“object”符号是/可能是什么类型的

这也是源于尖锐的引号(
#“
)操作符v.
符号函数
。我怀疑它们不同的唯一原因是,不是所有的名字都是符号,但我还没有足够的背景来理解这些答案(因此这个问题)


我还在elisp v.common lisp中要求澄清。我假设这与词法形式有关,直到版本24(我想是24.1)才在elisp中引入词法形式。

Lambda表达式不是函数名。只是
((Lambda(…))…)
在Common Lisp中是允许的,因为它在标准中定义为合法语法

Common Lisp中唯一允许的函数名是符号和列表,如
(setf symbol)

例如,一个人可以写作

(defun (setf foo) (...) ...)
这里
(setf foo)
是函数名

公共Lisp中不存在其他函数名,只有符号和
(setf symbol
)名称

通用Lisp Hyperspec词汇表:

(在环境中)符号或列表(setf) 符号),即该环境中函数的名称。2.a 符号或列表(setf符号)

注意:1984年的通用Lisp版本(发布于CLtL1)只有符号作为函数名。因此函数名的概念没有定义。从符号检索函数的函数称为
symbol-function
。1989年,ANSI CL标准化小组决定添加setf列表作为函数名。它还引入了函数
FDEFINITION
,类似于
SYMBOL-FUNCTION
,但也接受除符号以外的其他函数名。请参见此处:。

我认为这是正确的,但由于问题出现在对的评论中,我将包括(更新)我的回复

符号是一个实际对象。您可以检查它,也可以使用make symbol等创建它们。重要的是,符号是Common Lisp中源代码的主要组成部分。函数名称,尤其是在出现此问题的上下文中(函数的参数特殊运算符)根据术语表条目,是形式为(setf symbol)的符号或列表:

(在一个环境中)一个符号或一个列表(setf符号),它是该环境中一个函数的名称 符号或列表(setf符号)

Function是一种特殊的运算符,它不计算其参数,因此传递符号或setf列表意味着:

(function car)
(function (setf car))
而不是:

(function 'car)
(function '(setf car))
现在,词法变量,例如(let((x42))x中的x,虽然在源代码中由符号表示,但在运行时实际上与符号没有任何联系不需要知道关于符号x的任何信息。直观地说,这是有意义的,因为我们希望代码(let((y42))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)
          ...))
  ...)

值得一提的是(就像过去一样),这在Lisp上早于通用Lisp标准,因此Graham关于该语言的一些术语或假设并不完全一致。也就是说,确实有些符号是名称,但并非所有名称都是符号。@JoshuaTaylor:函数名的概念在1989年的标准化过程中被引入到通用Lisp中。它是已在CLtL2(1990年出版)中描述.On Lisp于1993年发布。On Lisp中的措辞看起来像是来自CLtL1…@RainerJoswig-Hmmm,我没有检查日期;我是基于此。@JoshuaTaylor:CLtL2发布了ANSI CL努力定义的语言,直到那时-在标准最终确定之前。但认为有必要发布更改/扩展,because用户需要更新CLtL1。甚至在此之前,lambda表达式不是函数名。CLtL1提到它在lambda表达式表单和函数内部被视为名称。但lambda表达式从来不是函数名。问题是“实现可以自由扩展函数名的语法,以包括以除SETF以外的其他符号开头的列表。”但我在hyperspec中找不到这个词。@SamuelEdwinWard:我认为这句话没有被纳入标准。