Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lambda 为什么这个小阴谋家里有那么多的羔羊?_Lambda_Scheme_The Little Schemer - Fatal编程技术网

Lambda 为什么这个小阴谋家里有那么多的羔羊?

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 (

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

(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。这意味着使用您提到的-style
define
创建函数是可能的,而且更紧凑

但是,当您开始使用函数作为一级值时,例如,作为的参数,您将第一次看到
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))