我正在阅读丹尼尔弗里德曼的 The Little Schemer 一书。我不明白为什么书中的每个函数都是用lambda表达式编写的。
(define fun1
(lambda (x1 x2)
(+ x1 x2)))
(define (fun2 x1 x2)
(+ x2 x2))
这两个功能做同样的事情,但第二个功能更整洁。我很好奇在各地使用lambda的原因。
在这种情况下我使用了DrRacket。
答案 0 :(得分:9)
(define (x . a) ...)
只是
的缩写(define x (lambda a ...))
在1975年的第一个方案报告中,你没有这个缩写。在1978年的修订报告中,它被引入。
小型Schemer 只是1974年 The Little Lisper 的后期版本。它早于Scheme,当修复为遵循Scheme时,他们试图保持的接近于尽可能原创。此外,当您使用(define x (lambda (arg1) ...))
时,很明显,过程绑定与其他变量绑定没有区别,除了它指向的对象是闭包代码而不是数据。
如果你看SICP video lectures,你会发现Abelson和Sussman确实让学生对此感到困惑,所以最好只使用其中一种,因为匿名程序是你最需要触及的东西。很明显,你想用一个明确的lambda来代替语法糖来教授这个形式。
答案 1 :(得分:4)
这只是风格问题。在The Little Schemer中,作者决定使用lambdas显式声明过程,以明确函数定义为过程赋予一个名称(这只是一个带有值的表达式,就像任何其他过程一样)。
声明函数的另一种方式(没有显式的lambdas)是完全等价的,它只是语法糖。有人可能会争辩说,作者为教学而非实际原因选择了更明确的语法。
答案 2 :(得分:0)
lambda表达式是函数文字,就像3(例如)是整数文字一样。你可以想象一种编程语言,你不能在一个更大的表达式中使用3,但必须定义一个变量并将其初始化为3.它仍然可以工作,但它会带来不便并妨碍你。大多数语言都与函数类似(它们只能被定义一次,然后被调用),但是函数式语言可以让你像处理任何其他变量一样处理函数,包括能够从字面上引用它们。
就像你需要一个特定的整数但不需要使用变量时使用整数文字一样,当你需要一个函数但不需要打扰它时,你可以使用一个lambda表达式。
常见的用途是使用mapcar这样的函数,它将函数作为参数,并将该函数应用于另一个参数中的所有元素。有时候你只想把一个一次性功能扔进去,而不需要命名。
只要看一下这个特定的例子,我猜他们会指出scheme和lisp之间的区别(lisp的确有些不同)。
答案 3 :(得分:0)
我自己刚刚完成 The Little LISPer 。最初,我很困惑为什么他们使用这个奇怪的习语。正如你所说,后者是前者的糖,当然看起来更整洁,那么在所有地方使用匿名函数有什么意义呢?
从教育学的角度来看,我认为它为读者做好了准备,最后的章节涵盖了currying,高阶函数,lambda演算等等。特别是,应用顺序Y组合子的推导需要在其他环境中使用你可能称之为“不必要的函数包装”的东西。通过倒数第二章,你对这个程序非常熟悉,推出Y-combinator并不比倒咖啡或做吐司更困难。好吧 - 不是真的,但我认为作者采用的风格无疑会让你更接近理解这个难题。