5

我正在阅读 Daniel Friedman 的The Little Schemer书。我不明白为什么书中的每个函数都是用 lambda 表达式编写的。

(define fun1
  (lambda (x1 x2)
    (+ x1 x2)))

(define (fun2 x1 x2)
  (+ x2 x2))

这两个函数做同样的事情,但第二个更整洁。我很好奇到处使用 lambda 的原因。

在这种情况下,我使用了 DrRacket。

4

4 回答 4

9
(define (x . a) ...) 

只是一个缩写

(define x (lambda a ...))

在 1975 年的第一份计划报告中,您没有这个缩写。在 1978 年的修订报告中引入了它。

小 Schemer只是 1974 年的The little Lisper的较新版本。它早于 Scheme,当固定遵循 Scheme 时,他们试图保持尽可能接近原始版本。此外,当您使用时(define x (lambda (arg1) ...)),很明显,过程绑定与其他变量绑定没有什么不同,除了它指向的对象是闭包代码而不是数据。

如果你看一下SICP 视频讲座,你会发现 Abelson 和 Sussman 确实有学生对此感到困惑,所以最好只使用其中一个,因为匿名程序是你最终需要接触的东西,很明显你想教具有显式 lambda 而不是语法糖的形式。

于 2013-12-30T13:11:40.763 回答
4

这只是风格问题。在 The Little Schemer 中,作者决定使用 lambdas 显式声明过程,以明确函数定义为过程分配名称(它只是一个带有值的表达式,就像任何其他的一样)。

声明函数的另一种方式(没有显式 lambdas)是完全等价的,它只是语法糖。有人可能会争辩说,作者出于教学而非实际原因选择了更明确的语法。

于 2013-12-30T13:04:47.353 回答
0

lambda 表达式是一个函数字面量,就像 3(例如)是一个整数字面量一样。您可以想象一种编程语言,您不能在更大的表达式中使用 3,但必须定义一个变量并将其初始化为 3。它仍然可以工作,但会很不方便并且会妨碍您。大多数语言都与函数类似(它们可以只定义一次然后调用),但是函数式语言让您可以像对待任何其他变量一样对待函数,包括能够逐字引用它们。

就像当你需要一个特定的整数但不需要打扰变量时使用整数文字一样,当你需要一个函数但不需要为它命名时,你可以使用 lambda 表达式。

一个常见的用途是使用像 mapcar 这样的函数,它将一个函数作为参数并将该函数应用于另一个参数中的所有元素。有时您只想在其中添加一次性功能,而无需为其命名。

只看那个特定的例子,我猜他们指出了方案和 lisp 之间的区别(lisp 的做法有些不同)。

于 2013-12-30T06:52:48.803 回答
0

我自己刚刚完成了The Little LISPer。最初,我对他们为什么使用这个奇怪的成语感到困惑。正如您所说,后者是前者的糖,当然看起来更整洁,那么到处使用匿名函数有什么意义呢?

从教学的角度来看,我认为它可以让读者更好地为最后几章做好准备,包括柯里化、高阶函数、lambda 演算等等。特别是,应用顺序 Y 组合子的推导需要在其他上下文中使用您可能称之为“不必要的函数包装”的东西。到倒数第二章,你已经非常熟悉这个过程,推导出 Y 组合子并不比倒咖啡或烤面包更难。好吧——不是真的,但我认为作者采用的风格肯定有助于让你更接近理解这个困难的想法。

于 2014-01-10T15:37:24.053 回答