Lambda 为什么这个小阴谋家里有那么多的羔羊?
在从SICP学习了一些Scheme之后,我开始阅读《小阴谋家》(我觉得很有趣),大约完成了四分之一。我注意到,我可以不用lambda编写许多(大多数?全部?)解决方案,而小Schemer总是使用它们。例如,第一个定义是Lambda 为什么这个小阴谋家里有那么多的羔羊?,lambda,scheme,the-little-schemer,Lambda,Scheme,The Little Schemer,在从SICP学习了一些Scheme之后,我开始阅读《小阴谋家》(我觉得很有趣),大约完成了四分之一。我注意到,我可以不用lambda编写许多(大多数?全部?)解决方案,而小Schemer总是使用它们。例如,第一个定义是 (define atom? (lambda (x) (and (not (pair? x)) (not (null? x))))) 除非我弄错了,否则可以更简单地写为 (define (atom? x) (and (not (pair? x)) (not (
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
除非我弄错了,否则可以更简单地写为
(define (atom? x)
(and (not (pair? x)) (not (null? x))))
如果我写的是lambda-less解决方案,我会错过一些基本的东西吗?最初,
define
有一个语法,将变量设置为值。这就是这些古老的(永恒的)书籍所采用的风格。稍后,define
使用了不同的语法作为快捷方式,这就是您正在使用的语法
只是为了好玩,在你的方案库中搜索,你可能会发现一个宏,它将非lambda形式扩展为旧的lambda重形式。我隐约记得一位教授讨论过这样的事情 我认为使用lambda解决方案有两个原因: 第一个是纯粹的历史事件。在某个时间点上,这是唯一可行的方法。所以有些人仍然使用这种方法 第二,有些人只是想更明确地说明函数正在被创建的事实,所以他们喜欢看到lambda这个词
因此,我相信选择取决于您个人最喜欢的内容。小计划者使用伪代码计划(为了教育目的进行简化,并独立于实现)。今天的标准方案有一个define定义,在该定义中隐式调用lambda(请参阅)。Little Schemer scheme非常简单,不包括这种替代形式。我非常喜欢使用
lambda
-厚重的教学风格,因为它使函数创建更加明确,正如Jay所说
学习时,您开始使用的简单函数(如atom?
)是顶级的define
d。这意味着使用您提到的-styledefine
创建函数是可能的,而且更紧凑
但是,当您开始使用函数作为一级值时,例如,作为的参数,您将第一次看到lambda
,它可能看起来比实际情况更奇怪、更神奇
相反,如果您一直在使用lambda
定义函数,那么看到函数与任何其他值一样就不那么容易了。它们经常出现在定义的右侧,但与数字或引用的常量没有区别:
(define x 1)
(define l '(2 3 4 5))
(define s (cons x ls))
(define f (lambda (n) (+ n 2)))
当然,语言支持这两种形式,因此最终归结为风格。对我来说,当所有函数都是由lambda
生成时,define
的用法有一种吸引人的一致性:第一个参数始终是一个符号,第二个参数只是任何旧表达式。事实上,lambda
与任何旧表达式一样,这是任何函数式程序员学习的最重要的事情之一。您可以看到您的方案是如何将这些快捷键(宏)扩展为使用扩展
(如果支持):
mzscheme 4.2.4(带DrScheme):
当我使用TLS时,lambda
看起来像白天一样简单。我正在读一些关于lambda演算的书(读Simon Peyton Jones的《函数式编程语言的实现》;免费pdf在线)。所以这只是一个猜测,但我相信TLS的作者希望你的思想真的很重。他们不会说出来,但有一些提示(查看TLS第107页)表明这只是应用lambda计算中的一个练习。因此,也许他们没有说,“你在做lambda抽象,我的朋友!”+1想到以与声明变量相同的方式声明函数,令人耳目一新:左边的name,右边的值。感谢您强调此方法的一致性方面;它补充了另一个解释。“事实上,lambda就像任何旧的表达式一样,这是任何函数式程序员学习的最重要的事情之一”-直到我通读了你的解释,我才明白这一点。@Andrè-我不认为这是对另一个答案的补充。在我看来,这是一个完全不同的答案。好的一个,如果你问我:-)只是用来说明宏在Scheme中有多么重要,即使define
是一个宏!lambda实际上是alpha和omegaNot——自从1978年第一次修订报告以来,“新的”define
形式就一直使用这种语言。在书中选择使用显式lambdas是一种风格/教学方法。我不知道。。。但是检查第一版(最初称为“小LISPer”)于1974年发行
> (expand '(define (add1 x) (+ 1 x)))
#<syntax (define-values (add1) (lambda...>
(define-values
(add1)
(lambda (x) (apply + '1 x)))
> (expand '(define (add1 x) (+ 1 x)))
(begin
(set! add1
(lambda (x)
(+ 1 x)))
(void))