为什么Little Schemer中的所有lambdas?

时间:2011-01-24 01:42:58

标签: lambda scheme the-little-schemer

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

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

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

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

如果我写一些没有lambda的解决方案,我是否遗漏了一些基本的东西?

6 个答案:

答案 0 :(得分:22)

我非常喜欢lambda - 重教学风格,因为它使函数创作更加明确,正如杰伊所说。

在学习时,您在atom?开始的简单功能在顶层是define d。这意味着使用您提到的defun - 样式define来创建函数是可能的,甚至更紧凑。

然而,当你开始使用函数作为第一类值时,例如,作为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就像任何旧表达式一样,是任何函数式程序员学习的最重要的事情之一。

答案 1 :(得分:14)

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

只是为了好玩,搜索您的Scheme库,您可能会发现一个宏将非lambda表单扩展为旧的lambda表单。

答案 2 :(得分:8)

您可以看到您的Scheme将这些快捷方式(宏)扩展为使用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 Scheme 8.0:

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

lambda显示为白天。

答案 3 :(得分:4)

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

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

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

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

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

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