为什么 Common-Lisp Lambda 表达式是有效的函数名?

Cha*_*lim 2 lambda common-lisp function-call

所以假设我想调用一些函数。如果我用 defun 定义了函数,我只需在列表的开头使用函数的名称,然后使用它的参数,就像这样(我将在示例中使用“=>”来显示输入代码的输出进入 CLisp REPL):

(defun f (a) (lambda (b) (+ a b))) => F
(f 12) => #<FUNCTION :LAMBDA (B) (+ A B)>
Run Code Online (Sandbox Code Playgroud)

足够简单。列表的第一个元素必须是函数、特殊运算符或宏的名称。除此之外,以下内容也有效:

((lambda (a) (+ a 12)) 1) => 13
Run Code Online (Sandbox Code Playgroud)

快速谷歌搜索显示 LAMBDA 既是一个符号又是一个宏。试图扩大宏产量:

(macroexpand '(lambda (a) (+ a 12))) => #'(LAMBDA (A) (+ A 12))
Run Code Online (Sandbox Code Playgroud)

这没有帮助。我无法区分宏 LAMBDA 和符号 LAMBDA,而且我完全不清楚为什么我可以使用 lambda 表达式作为函数名而不是 #'f,据我所知,应该以与 #'(LAMBDA (A) (+ A 12)) 相同的方式计算函数 F 的有效函数指示符,但是:

(#'f 12) => *** - EVAL: #'F is not a function name; try using a symbol instead
Run Code Online (Sandbox Code Playgroud)

LAMBDA 是其他硬设置规则的特殊例外,即评估表达式的第一个元素必须是某个操作的名称,还是有一些我误解的更一致的规则集?

Rai*_*wig 6

Lambda 表达式和函数名称

lambda表达式不是函数名。Common Lisp 中的函数名称被定义为符号(setf 符号)。一个lambda表达式基本上是内置的语法来描述一个匿名函数。

请注意,lambda 表达式本身在 Common Lisp 中没有意义。它们仅以lambda 形式(见下文)和带有特殊运算符 的形式出现function

列表形式

LAMBDA 是其他硬设置规则的特殊例外,即评估表达式的第一个元素必须是某个操作的名称,还是有一些我误解的更一致的规则集?

Common Lisp 规范定义只有四种基于列表的表单。甲形式是有效的Lisp一段代码。

  • 特殊形式(形式以特殊运算符开头)
  • 宏形式(形式以宏运算符开头)
  • 函数形式(形式以函数运算符开头)
  • lambda 形式(该形式以 lambda 表达式开头)

参见 Common Lisp HyperSpec: Conses as Forms

请注意,Common Lisp 中没有扩展此功能的机制。只有这四种类型的基于列表的表单。人们可以将扩展想象成:数组作为函数,CLOS 对象作为函数,不同类型的函数,如 fexprs、变量,...... Common Lisp 语法都不支持基于列表的表单,并且没有可移植的机制来添加这些.

拉姆达

LAMBDA 在 Common Lisp 中有两个不同的目的:

  • 它是lambda 表达式的头部。
  • 作为宏LAMBDA。这扩展(lambda ....)(function (lambda ....))

LAMBDA在第一个语言定义 CLtL1 之后,该宏被添加到 Common Lisp 中,以便能够(lambda (x) x)代替(function (lambda (x) x))or编写#'(lambda (x) x)。因此它是函数特殊运算符形式的缩写,使代码看起来更简单,更像Scheme