首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当‘is’被重新定义时,无休止的递归,为什么?

当‘is’被重新定义时,无休止的递归,为什么?
EN

Stack Overflow用户
提问于 2019-06-20 16:14:15
回答 2查看 125关注 0票数 1

我刚开始编程,开始学习语言计划。(我研究了书的结构和计算机程序的解释),有一项任务如下所述。我编写了两段用cond代替cond的代码,但是由于某种原因,在运行第一段代码时会有没完没了的递归,但是当运行第二段代码时,就不会有无休止的递归,它通常计算的是sqrt...although --代码是相同的,为什么呢?

AlyssaP.Hacker不明白为什么需要将if作为一种特殊形式提供。“为什么我不能用cond把它定义为一个普通的过程呢?”她问。Alyssa的朋友Eva Lu Ator声称这确实是可以做到的,她定义了一个新版本的if

代码语言:javascript
复制
(define (new-if predicate then-clause else-clause)
    (cond (predicate then-clause)
        (else else-clause)))

Eva演示了Alyssa的程序:

代码语言:javascript
复制
(new-if (= 2 3) 0 5)
5

(new-if (= 1 1) 0 5)
0

Alyssa很高兴地使用new-if重写square-root程序:

代码语言:javascript
复制
(define (sqrt-iter guess x)
    (new-if (good-enough? guess x)
    guess
    (sqrt-iter (improve guess x)
        x)))

当Alyssa试图使用它计算平方根时会发生什么?解释一下。

第一法典:

代码语言:javascript
复制
(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

(define (square x)
  (* x x))

(define (average x y)
  (/ (+ x y) 2))

(define (improve guess x)
  (average guess (/ x guess)))

(define (better-good-enough? prev-guess guess)
  (< (abs (- guess prev-guess))
     0.00001))

(define (better-sqrt-iter prev-guess guess x)
  (new-if (better-good-enough? prev-guess guess)
      guess
      (better-sqrt-iter guess
                        (improve guess x)
                        x)))

(define (better-sqrt x)
  (better-sqrt-iter 0 1.0 x))

第二部法典:

代码语言:javascript
复制
(define (square x)
  (* x x))

(define (average x y)
  (/ (+ x y) 2))

(define (improve guess x)
  (average guess (/ x guess)))

(define (better-good-enough? prev-guess guess)
  (< (abs (- guess prev-guess))
     0.00001))

(define (better-sqrt-iter prev-guess guess x)
  (cond ((better-good-enough? prev-guess guess)
      guess)
        (else (better-sqrt-iter guess
                        (improve guess x)
                        x))))

(define (better-sqrt x)
  (better-sqrt-iter 0 1.0 x))
EN

回答 2

Stack Overflow用户

发布于 2019-06-20 17:02:48

这闻起来像是一个家庭作业问题,但是,假设您使用的是Scheme,那么考虑一下当一个普通表单(所以,不是任何一种特殊形式)像这样时会发生什么

代码语言:javascript
复制
(f a b c)

评价如下:

  1. fab & c按某种未定义的顺序(可能是一次甚至一次)计算;
  2. f (即评价它的结果)的值作为一个函数应用于abc的评价结果;
  3. 函数返回一个值(或多个值),这是表单的值。

当您使用此评估策略尝试评估better-sqrt-iter的第一个版本时,会发生什么?你可以用纸和铅笔做一些评估,看看会发生什么。

为什么这个评估规则在这里是个问题?

票数 1
EN

Stack Overflow用户

发布于 2019-06-20 21:52:00

我们可以使用替代模型。

代码语言:javascript
复制
(better-sqrt 1) 
(better-sqrt-iter 0 1.0 1)
(cond
  ((better-good-enough? 0 1.0) 1.0)
  (else
   (better-sqrt-iter 1.0
                     (improve 1.0 1)
                     1))))
(cond
  (#f 1.0)
  (else
   (better-sqrt-iter 1.0
                     (improve 1.0 1)
                     1))))

(better-sqrt-iter 1.0
                  (improve 1.0 1)
                  1)
(better-sqrt-iter 1.0
                  1.0
                  1)
(cond
  ((better-good-enough? 1.0 1.0) 1.0)
  (else
   (better-sqrt-iter 1.0
                     (improve 1.0 1.0)
                     1))))
(cond
  (#t 1.0)
  (else
   (better-sqrt-iter 1.0
                     (improve 1.0 1.0)
                     1))))
1.0

现在让我们对new-if进行同样的尝试

代码语言:javascript
复制
(better-sqrt 1) 
(better-sqrt-iter 0 1.0 1)

方案说,您可以按任何顺序评估过程。我从右向左选择!

代码语言:javascript
复制
(new-if (better-good-enough? 0 1.0) 
        1.0
        (better-sqrt-iter 1.0
                          (improve 1.0 1)
                          1))
(new-if (better-good-enough? 0 1.0) 
        1.0
        (new-if (better-good-enough? 1.0 1.0) 
                1.0
                (better-sqrt-iter 1.0
                                  (improve 1.0 1)
                                  1)))
(new-if (better-good-enough? 0 1.0) 
        1.0
        (new-if (better-good-enough? 1.0 1.0) 
                1.0
                (new-if (better-good-enough? 1.0 1.0) 
                        1.0
                        (better-sqrt-iter 1.0
                                          (improve 1.0 1)
                                          1))))
(new-if (better-good-enough? 0 1.0) 
        1.0
        (new-if (better-good-enough? 1.0 1.0) 
                1.0
                (new-if (better-good-enough? 1.0 1.0) 
                        1.0
                        (new-if (better-good-enough? 1.0 1.0) 
                                1.0
                                (better-sqrt-iter 1.0
                                                  (improve 1.0 1)
                                                  1)))))
;; goes on like this forever!

请注意,我从未执行过任何good-enough调用,因为所有3个表达式都需要在计算new-if主体之前完成,而内置if则首先计算测试表达式,然后根据测试表达式的计算结果,只计算一个后续表达式或替代表达式,从而停止递归。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56690099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档