Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么要引用lambda表达式?_Lambda_Lisp_Elisp_Common Lisp_Sharp Quote - Fatal编程技术网

为什么要引用lambda表达式?

为什么要引用lambda表达式?,lambda,lisp,elisp,common-lisp,sharp-quote,Lambda,Lisp,Elisp,Common Lisp,Sharp Quote,这是在通用Lisp上的On Lisp中经常使用的一种技术: > (mapcar #'(lambda (x) (+ x 10)) '(1 2 3)) (11 12 13) 为什么需要或甚至可能采用尖锐的报价?lambda表达式返回函数对象,而尖引号从名称返回函数对象。我还听到过关于lambda表达式是否是名称的相互矛盾的信息——特别是在Lisp上,这与标准相矛盾,但他的代码似乎工作正常,这也与标准相矛盾 在elisp。令我惊讶的是,这其中没有讨论词法范围,所以不清楚为什么

这是在通用Lisp上的On Lisp中经常使用的一种技术:

> (mapcar #'(lambda (x) (+ x 10))
         '(1 2 3))
(11 12 13)
为什么需要或甚至可能采用尖锐的报价?lambda表达式返回函数对象,而尖引号从名称返回函数对象。我还听到过关于lambda表达式是否是名称的相互矛盾的信息——特别是在Lisp上,这与标准相矛盾,但他的代码似乎工作正常,这也与标准相矛盾

在elisp。令我惊讶的是,这其中没有讨论词法范围,所以不清楚为什么它应该与普通Lisp完全不同。但是他说,不带引号的lambda表达式毫无意义,因此,具有讽刺意味的是,有可能引入不带引号的lambda表达式作为带引号的表达式的语法糖。但这与“在Emacs Lisp中,这样的列表是一个有效的表达式,其计算结果为函数对象”的说法相矛盾


这个问题被标记为common-lisp和e-lisp,因为我试图理解这两个问题背后的理论模型,并通过学习它们的差异来学习它们。(更实际地说,我正在尝试学习elisp,但在Common Lisp上发现了很多很好的资源,所以我正在学习这两种语言)。

简而言之,你不必尖锐地引用
lambda
,因为它是一个扩展到
(函数(lambda…)
,而
函数
才是最神奇的

函数
不必要的唯一意义是您不必自己键入它。基本运算符是
函数
,而不是
λ
。Lambda表达式本身只是普通的列表(它知道如何将函数对象转换为函数对象),而
Lambda
只是一个普通的宏。因此,我们把事情弄得相当倒退:lambda表达式返回函数对象并不能排除
function
,因为
lambda
是用
function
来解释的


另外一个问题是,在Emacs Lisp中,以
lambda
开头的列表可以直接作为函数处理,而不必经过
function
。CL中的情况并非如此(尽管显式转换以
(强制某些列表的函数)
的形式提供)。

这一切都与历史有关<代码>(lambda…只是
#'(lambda…)
的语法糖。Common Lisp的早期版本没有将
lambda
定义为宏。如果您阅读(PD,第2页),您会看到他明确表示您需要创建如下宏:

(defmacro lambda (args &body body)
  "Allow (lambda (x) ...) instead of #'(lambda (x) ...)"
  `#'(lambda ,args .,body))
因此,今天在编写
(lambda…
时,标准宏会将其重写为
#'(lambda…

是一本旧书,它可能在宏成为标准之前首次出版。也可能是保罗·格雷厄姆(Paul Graham)习惯于写
#'(lambda…
),并且一直坚持写下去

我已经看到,当符合更新的标准时,计算机书籍的后期版本通常会尽可能少地改变。我不确定这是件好事

假定使用公共Lisp

为什么需要或甚至可能采用尖锐的报价

如果要从函数名(特别是要引用词法绑定)或lambda表达式计算函数对象,则需要特殊运算符
函数
,或更短的
#'

lambda表达式返回函数对象

他们没有甚至无法计算Lambda表达式。

在Common Lisp中,它看起来像是可以计算
(lambda()nil)
。但它不能

CLtL1之后的某个时间,添加了一个宏
LAMBDA
,将其扩展为
(函数…
表达式。这个宏保存了一些输入,让代码看起来更像Scheme。让我们检查一下这个
LAMBDA
宏:

CL-USER 17 > (macroexpand-1 '(lambda () ()))  ; not a lambda expression
(FUNCTION 
  (LAMBDA NIL NIL)                            ; <- this is a lambda expression
)
T
因为上面是一个宏表单,所以将首先展开它,然后对其进行求值

CL-USER 19 > (function          ; <- this is a special form
              (lambda () ())    ; <- this is a lambda expression
              )
#<anonymous interpreted function 4060000C0C>
上面再次显示了lambda表达式。其中,
((函数(lambda()))
不是有效的公共Lisp。在函数调用的函数位置,Common Lisp需要函数名或lambda表达式,而不是需要计算的内容

CL-USER 19 > (function          ; <- this is a special form
              (lambda () ())    ; <- this is a lambda expression
              )
#<anonymous interpreted function 4060000C0C>
和尖引号从名称返回函数对象

函数
,它的
#
是一个简短的表示法,从函数名lambda表达式返回函数对象

请参阅文档:

我还听到过关于lambda表达式是否是名称的相互矛盾的信息——特别是在Lisp上,这与标准相矛盾,但他的代码似乎工作正常,这也与标准相矛盾

如果你想听到最后一句话,请阅读ANSI CL标准。或者使用通用的Lisp Hyperspec,它是web可读的,并且源于标准

在Lisp上阅读肯定很有用,但它可能不会完全遵循ANSI CL的措辞或语义。在CLtL2之后,但在ANSI CL之前发布了On Lisp

编写代码的实际意义是什么?

如果您像我一样年纪大了,而且CLtL1是您最后一次阅读Common Lisp的内容,那么请编写如下代码:

(mapcar #'(lambda (x) (* x x)) '(1 2 3))
如果您年纪更大,是在Scheme环境中长大的,或者更年轻,并且已经阅读了常见的Lisp Hyperspec,那么您可能想写:

(mapcar (lambda (x) (* x x)) '(1 2 3))
(mapcar #'sin '(1 2 3))
但对于所有人来说,当涉及函数名时,这是默认的写入方式:

(mapcar (lambda (x) (* x x)) '(1 2 3))
(mapcar #'sin '(1 2 3))

函数
关键字在不同的Lisp语言中似乎有不同的含义

在Lisp1.5中,它用于使用
funarg
设备创建闭包。 参考:,以及LISP 1.5程序员手册,附录B

在MacLisp中,它被用作编译器的提示,表示lambda表达式可以编译为代码。参考文献:。它不是用来创建闭包的;
*函数
特殊形式也做了类似的事情。参考资料

在Emacs Lisp中,它是对编译器的提示,并且