lambda - 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?
解决方案
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。
推荐阅读
- javascript - 将 JSON 存储到本地存储不起作用
- apache-spark - pyspark 流式传输:无法对工作人员执行 rdd.count()
- openstack - 如何创建具有随机密码的用户?
- apache-flink - 在 Flink 中解析 JSON 时如何处理异常
- vba - 使用 VBA 与列表匹配的数据验证
- mysql - SQL 使用外键连接两个表
- linux - 远程访问 virtualenv
- vim - 如何绑定一个键以使用vim打开突出显示的文件?
- javascript - ChargeBee Drop-in checkout + React:错误
- python - fetch_mldata:当源服务器关闭时如何手动设置 MNIST 数据集?