正常评估过程(Scheme)?

时间:2015-08-10 02:53:51

标签: scheme sicp

我正在学习SICP,ex1.20给出了以下代码:

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

当我们分别以应用顺序和正常顺序运行(gcd 206 40)时,问题会询问剩余时间。我可以弄清楚剩余被按照应用顺序被召唤4次,但是我不明白为什么它在正常秩序时会变成18。在我看来,首先调用(gcd 40 (remainder 206 40)),接下来我们需要计算(remainder 206 40),即6,如果我们想知道我们去哪个分支,然后(remainder 40 6),那么在,它也是4次。但答案给出了以下过程:

     (gcd 206 40) 

     (if (= 40 0) ...) 

     (gcd 40 (remainder 206 40)) 

     (if (= (remainder 206 40) 0) ...) 

     (if (= 6 0) ...) 

     (gcd (remainder 206 40) (remainder 40 (remainder 206 40))) 

     (if (= (remainder 40 (remainder 206 40)) 0) ...) 

     (if (= 4 0) ...) 

     (gcd (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 

     (if (= (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) 0) ...) 

     (if (= 2 0) ...) 

     (gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))) 

     (if (= (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) 0) ...) 

     (if (= 0 0) ...) 
     (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) 

所以总共是18次。 我认为两个答案之间的主要区别在于,我认为一旦计算出余数,就不再需要计算,但答案似乎每次都可以计算出来。这是编译器的问题吗?这不是太有效吗?

1 个答案:

答案 0 :(得分:2)

编辑:实际上,我所说的正常订单是按名称调用。懒惰是按需调用,两者都是正常的顺序。

你的直觉对于应用顺序是正确的,其中在函数调用之前评估参数(即它们的值被发现)。但是按照正常的顺序,它们只在函数调用中内部进行评估,当需要它们的值时 - 然后,这个值被遗忘了。顺便说一下,记住找到的值的正常顺序称为 lazy 评估。

因此,评估的适用顺序的减少顺序是

> (gcd 206 40)
= (if (= 40 0) 206 (gcd 40 (remainder 206 40)))
= (gcd 40 (remainder 206 40))
> (remainder 206 40) => 6
= (gcd 40 6)
= (if (= 6 0) 40 (gcd 6 (remainder 40 6)))
= (gcd 6 (remainder 40 6))
> (remainder 40 6) => 4
= (gcd 6 4)
....

但是对于正常的顺序,它将是

> (gcd 206 40)
= (if (= 40 0) 206 (gcd 40 (remainder 206 40)))
= (gcd 40 (remainder 206 40))
= (if (= (remainder 206 40) 0) 40 
                   (gcd (remainder 206 40) (remainder 40 (remainder 206 40))))
....

你可以看到差异。