中考考点1.20的寓意?

问题描述 投票:1回答:1

在这个练习中,要求我们用先正序再应用序评价的方法来追踪Euclid的算法。

(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))

我做了手工跟踪,并与网上的几种解法进行了对照。我在这里很想巩固一下这个练习的寓意。

gcd 上文指出 b 在函数体中被重复使用三次。加上 这个函数是递归的。这就是为什么会产生18次对 remainder ,而应用顺序只有4。

所以,似乎当一个函数在其主体中使用一个参数不止一次时,(也许是递归的!就像这里一样),那么在调用函数时就不对其进行评估(即应用顺序)。 导致同一事物的多余的重新计算。

请注意,本题不厌其烦地指出,特殊形式的 if 当使用正常顺序时,不会改变其行为,即: if 总是会先运行;如果不发生这种情况,在这个例子中就不会有终止。

我对我们在这里看到的延迟评估感到好奇。

作为一个优点,它可能允许我们处理无限的东西,比如流.作为一个缺点,如果我们有一个像这里这样的函数,它可能会导致极大的低效率.要解决后者,似乎有两个概念性的选择。一,将其包裹在一些数据结构中,缓存其结果以避免重新计算。二,当你知道它否则会造成重复的重新计算时,有选择地强制参数实现。

问题是,这两个选项似乎都不是很好,因为这两个选项都代表了程序员必须知道如何使用和选择何时使用的额外 "杠杆"。

这一切是否会在本书的后面更彻底地处理呢?有没有什么直接整合这些要点的方法,值得在此时说明(也许不需要讲到后面的所有细节)。

sicp
1个回答
1
投票

简短的回答是肯定的,这在本书后面有广泛的介绍。

在第4章中会有最详细的介绍,在这里我们实现了eval和apply,因此有机会修改它们的行为。 例如练习4.31建议使用以下语法。

(define (f a (b lazy) c (d lazy-memo))

正如你所看到的,这确定了三种不同的行为。

  • 参数 ac 有适用顺序(它们被评价为 之前 它们被传递给 f).
  • b 是正常的或懒惰的,每次使用时都会被评估(但只有在使用时才会被评估)。
  • d 是懒惰的,但它的值是记忆的,所以它最多被评估一次。

虽然这种语法是可能的,但并没有被使用。 我认为其原理是,语言有一个预期的行为(应用顺序),而正常的顺序只是在必要的时候才会被默认使用(例如,一个语言的结果和替代的 if 语句,以及在创建流时)。) 当有必要(或希望)使用一个具有正常评估的参数时,我们可以使用 delayforce,必要时 memo-proc 如习题3.77)。

所以在这一点上,作者是在介绍正常顺序和应用顺序的概念,以便我们在后面进入具体的内容时,对它们有一定的熟悉度。

某种意义上这是一个反复出现的主题,应用性顺序可能更直观,但有时我们需要正常顺序。 递归函数的编写比较简单,但有时我们需要迭代函数的性能。 我们可以使用代用模型的程序更容易推理,但有时我们需要环境模型,因为我们需要可突变的状态。

© www.soinside.com 2019 - 2024. All rights reserved.