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

mag*_*age 3 common-lisp

我理解,因为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问题,该问题#'仅因历史原因而被保留,不应再使用了.这是真的?我的问题不是重复,我问我何时会在我的代码中使用这些.

Jos*_*lor 6

这不是lisp-2与lisp-1的问题.将lambda表达式放在需要函数值的位置,它只是一种风格选择.有些人喜欢视觉标记而有些人喜欢#'.的lambda已经扩展到function用于其形式#'提供的缩写:

LAMBDA

    (lambda lambda-list [[declaration* | documentation]] form*)
 ==  (function (lambda lambda-list [[declaration* | documentation]] form*))
 ==  #'(lambda lambda-list [[declaration* | documentation]] form*)
Run Code Online (Sandbox Code Playgroud)

#'x只是语法糖(function x),function特殊运算符提供"当前词汇环境中名称的功能价值".Ť

特殊操作员 功能

function的值是当前词法环境中name的功能值.

如果name是一个函数名,那么该名称的功能定义是由最里面的词法封闭的flet,labels或macrolet形式建立的,如果有的话.否则返回函数名的全局功能定义.

虽然(lambda ...)是一个函数的名称,它并不可能永远被建立的名称flet,labelmacrolet形式,所以你总是给我,这就是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表达式).

  • @mbratch只需给它一些时间,在这里闲逛,在comp.lang.lisp上,浏览HyperSpec.它会随着时间而来.:) (2认同)