19

在从 SICP 学习了一些 Scheme 之后,我开始阅读 The Little Schemer(我觉得这本书很有趣),大约完成了四分之一。我注意到我可以在不使用 lambda 的情况下编写许多(大多数?全部?)解决方案,而 The Little Schemer总是使用它们。例如,第一个定义是

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))

除非我弄错了,否则可以更简单地写成

(define (atom? x) 
   (and (not (pair? x)) (not (null? x))))

如果我编写无 lambda 解决方案,我是否缺少一些基本的东西?

4

6 回答 6

23

正如 Jay 所说,我非常喜欢lambda-heavy 的教学风格,因为它使函数创建更加明确。

学习的时候,你一开始喜欢的简单函数在顶层atom?都是d。这意味着可以使用您提到的-styledefine创建函数,甚至更紧凑。defundefine

但是,当您开始将函数用作一等值时,例如,作为 的参数map,您将lambda第一次看到它,它可能看起来比实际更奇怪和更神奇。

相反,如果你一直在定义你的函数lambda,那么看到函数就像任何其他值一样,并不是一个飞跃。它们碰巧经常出现在右边define,但与数字或引用的常量没有什么不同:

(define x 1)
(define l '(2 3 4 5))
(define s (cons x ls))
(define f (lambda (n) (+ n 2)))

当然,该语言支持这两种形式,因此最终归结为样式。define对我来说,当你的所有函数都用 来创建时,有一个吸引人的一致性lambda:第一个参数总是一个符号,第二个参数只是任何旧表达式。事实上,lambda就像任何旧表达式一样,这是任何函数式程序员要学习的最重要的事情之一。

于 2011-01-24T03:02:26.543 回答
15

最初,define只有一种语法,可以将变量设置为值。这就是这些古老(和永恒的)书籍中使用的风格。后来,define得到了一种不同的语法作为快捷方式,这就是您正在使用的快捷方式。

只是为了好玩,在您的 Scheme 库中搜索,您可能会发现一个将非 lambda 形式扩展为旧的 lambda-heavy 形式的宏。

于 2011-01-24T01:49:57.417 回答
8

您可以看到您的方案将这些快捷方式(宏)扩展为使用什么expand(如果支持):

mzscheme 4.2.4(与 DrScheme):

> (expand '(define (add1 x) (+ 1 x)))
#<syntax (define-values (add1) (lambda...>
(define-values
  (add1)
  (lambda (x) (apply + '1 x)))

Chez 计划 8.0:

> (expand '(define (add1 x) (+ 1 x)))
(begin
  (set! add1
    (lambda (x)
      (+ 1 x)))
  (void))

lambda看起来平淡无奇。

于 2011-01-24T03:42:56.477 回答
4

我依稀记得一位教授讨论过这样的事情。

我认为使用 lambda 解决方案有两个原因:

第一个纯粹是历史的事情。在某个时间点,这是唯一可行的方法。所以有些人仍然使用这种方法。

第二个是有些人只是喜欢更明确地说明正在创建一个函数的事实,所以他们喜欢看到 lambda 这个词。

所以我相信选择取决于你个人最喜欢的东西。

于 2011-01-24T01:50:49.823 回答
2

当我使用 TLS 时,我正在阅读一些关于 lambda 演算的内容(阅读 Simon Peyton Jones 的“函数式编程语言的实现”;在线免费 pdf)。所以这只是一个猜测,但我相信 TLS 的作者希望你在思考中真正重视 lambda。他们没有说出来,但有一些提示(查看 TLS 的第 107 页)这只是应用 lambda calc 的一个练习。所以也许他们会说,“你在做 lambda 抽象,我的朋友!”

于 2012-05-15T16:34:51.080 回答
1

Little Schemer 使用伪代码方案(为了教育目的进行简化并独立于实现)。今天的标准方案有一个定义的定义,其中隐式调用 lambda(参见http://www.cs.cmu.edu/Groups/AI/html/r4rs/r4rs_7.html)。Little Schemer 方案非常简单,不包括这种替代形式。

于 2011-01-24T01:53:08.480 回答