何时在lambda表达式前使用#'(函数)?

时间:2014-02-03 21:50:35

标签: common-lisp

我理解,因为Common Lisp中有函数和变量的单独命名空间,你可以这样做:

((lambda (x) (* 2 x)) 3)

你也可以这样做:

(funcall #'(lambda (x) (* 2 x)) 3)

我们应该何时使用#'而不是使用它?我在另一个StackOverflow问题中读到#'仅因历史原因而被保留,不应再使用了。这是真的?我的问题不是重复,我问我何时会在我的代码中使用这些。

1 个答案:

答案 0 :(得分:6)

这不是lisp-2与lisp-1的问题。如果lambda表达式位于需要函数值的位置,那么它只是一种风格选择。有些人喜欢#'的视觉标记,有些则不喜欢。 lambda macro已扩展为function表单,#'提供缩写:

  

Macro LAMBDA

    (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

  

Special Operator FUNCTION

     

函数的值是当前名称的功能值   词汇环境。

     

如果name是函数名,则该名称的功能定义是   由最内部的词汇封闭的flet,标签或者   macrolet表单,如果有的话。否则全球功能   返回函数名称的定义。

虽然(lambda ...)是函数的名称,但它不是fletlabelmacrolet形式可以建立的名称,所以你'总是得到“函数名称的全局定义”,这只是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)