我理解,因为Common Lisp中有函数和变量的单独命名空间,你可以这样做:
((lambda (x) (* 2 x)) 3)
你也可以这样做:
(funcall #'(lambda (x) (* 2 x)) 3)
我们应该何时使用#'
而不是使用它?我在另一个StackOverflow问题中读到#'
仅因历史原因而被保留,不应再使用了。这是真的?我的问题不是重复,我问我何时会在我的代码中使用这些。
答案 0 :(得分:6)
这不是lisp-2与lisp-1的问题。如果lambda
表达式位于需要函数值的位置,那么它只是一种风格选择。有些人喜欢#'
的视觉标记,有些则不喜欢。 lambda
macro已扩展为function
表单,#'
提供缩写:
(lambda lambda-list [[declaration* | documentation]] form*) == (function (lambda lambda-list [[declaration* | documentation]] form*)) == #'(lambda lambda-list [[declaration* | documentation]] form*)
#'x
只是(function x)
的语法糖,而function
special operator提供了“当前词汇环境中名称的功能价值”。 T
函数的值是当前名称的功能值 词汇环境。
如果name是函数名,则该名称的功能定义是 由最内部的词汇封闭的flet,标签或者 macrolet表单,如果有的话。否则全球功能 返回函数名称的定义。
虽然(lambda ...)
是函数的名称,但它不是flet
,label
或macrolet
形式可以建立的名称,所以你'总是得到“函数名称的全局定义”,这只是lambda函数。由于(lambda ...)
扩展为(function (lambda ...))
,因此没有区别。这只是风格问题。
但是,重要的是要注意在你谈到的第一个案例中,
((lambda (x) (* x 2)) 3)
你无法做:
(#'(lambda (x) (* x 2)) 3) ; or
((function (lambda (x) (* x 2))) 3)
对((lambda ...) ...)
的支持是该语言的一部分,与将lambda
定义为宏的事实无关。它是compound form的一种特殊类型,即lambda form,在HyperSpec中有描述:
3.1.2.1.2.4 Lambda Forms
lambda表单与函数表单类似,但函数除外 name被lambda表达式替换。
lambda形式相当于使用词法闭包的funcall 给定参数的lambda表达式。 (在实践中,一些 编译器更有可能为lambda表单生成内联代码 比内联声明的任意命名函数; 但是,这种差异并不是语义上的。)
有关详细信息,请参阅Section 3.1.3 (Lambda Expressions)。