首页 > 解决方案 > Why is a Common-Lisp Lambda expression a valid function name?

问题描述

So let's say I want to call some function. If I've defined the function with a defun, I just use the name of the function at the beginning of a list followed by it's arguments like so (I will be using "=>" in examples to show the output of entering the code into the CLisp REPL):

(defun f (a) (lambda (b) (+ a b))) => F
(f 12) => #<FUNCTION :LAMBDA (B) (+ A B)>

Simple enough. The first element of the list must be the name of a function, special operator, or macro. Except, the following is also valid:

((lambda (a) (+ a 12)) 1) => 13

A quick google-search reveals that LAMBDA is both a symbol and a macro. Trying to expand the macro yeilds:

(macroexpand '(lambda (a) (+ a 12))) => #'(LAMBDA (A) (+ A 12))

This is not helpful. I have no way to differentiate between the macro LAMBDA and the symbol LAMBDA, and I'm totally unclear as to why I can use a lambda expression as a function-name but not, say, #'f, which, to my knowledge, should evaluate to a valid function-designator for the function F in the same way that #'(LAMBDA (A) (+ A 12)) does and yet:

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

Is LAMBDA a special exception to the otherwise hard-set rule that the first element of an evaluated expression must be the name of some operation, or is there some more consistent ruleset that I'm misunderstanding?

标签: lambdacommon-lispfunction-call

解决方案


Lambda 表达式和函数名称

lambda 表达式不是函数名。Common Lisp 中的函数名被定义为符号(setf symbol)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


推荐阅读