我理解,因为Common Lisp中有函数和变量的单独命名空间,你可以这样做:
((lambda (x) (* 2 x)) 3)
Run Code Online (Sandbox Code Playgroud)
你也可以这样做:
(funcall #'(lambda (x) (* 2 x)) 3)
Run Code Online (Sandbox Code Playgroud)
什么时候应该使用#'
而不是不使用它?我读了另一个StackOverflow问题,该问题#'
仅因历史原因而被保留,不应再使用了.这是真的?我的问题不是重复,我问我何时会在我的代码中使用这些.
这不是lisp-2与lisp-1的问题.将lambda
表达式放在需要函数值的位置,它只是一种风格选择.有些人喜欢视觉标记而有些人喜欢#'
.的lambda
宏已经扩展到function
用于其形式#'
提供的缩写:
Run Code Online (Sandbox Code Playgroud)(lambda lambda-list [[declaration* | documentation]] form*) == (function (lambda lambda-list [[declaration* | documentation]] form*)) == #'(lambda lambda-list [[declaration* | documentation]] form*)
#'x
只是语法糖(function x)
,function
特殊运算符提供"当前词汇环境中名称的功能价值".Ť
function的值是当前词法环境中name的功能值.
如果name是一个函数名,那么该名称的功能定义是由最里面的词法封闭的flet,labels或macrolet形式建立的,如果有的话.否则返回函数名的全局功能定义.
虽然(lambda ...)
是一个函数的名称,它并不可能永远被建立的名称flet
,label
或macrolet
形式,所以你总是给我,这就是lambda函数"功能名的全局定义".从(lambda ...)
扩展到(function (lambda ...))
,没有区别.这只是一种风格问题.
但是,重要的是要注意,在你谈到的第一个案例中,
((lambda (x) (* x 2)) 3)
Run Code Online (Sandbox Code Playgroud)
你不能做的:
(#'(lambda (x) (* x 2)) 3) ; or
((function (lambda (x) (* x 2))) 3)
Run Code Online (Sandbox Code Playgroud)
支持((lambda ...) ...)
是语言的一部分,与lambda
作为宏的定义无关.它是一种特殊类型的复合形式,即lambda形式,在HyperSpec中有描述:
3.1.2.1.2.4 Lambda表格
lambda表单类似于函数表单,除了函数名称由lambda表达式替换.
lambda表单等效于在给定参数上使用lambda表达式的词法闭包的funcall.(实际上,一些编译器更有可能为lambda表单生成内联代码,而不是已经内联声明的任意命名函数;但是,这种差异不是语义上的.)
有关详细信息,请参见第3.1.3节(Lambda表达式).