我刚开始编程,开始学习语言计划。(我研究了书的结构和计算机程序的解释),有一项任务如下所述。我编写了两段用cond代替cond的代码,但是由于某种原因,在运行第一段代码时会有没完没了的递归,但是当运行第二段代码时,就不会有无休止的递归,它通常计算的是sqrt...although --代码是相同的,为什么呢?
AlyssaP.Hacker不明白为什么需要将
if作为一种特殊形式提供。“为什么我不能用cond把它定义为一个普通的过程呢?”她问。Alyssa的朋友Eva Lu Ator声称这确实是可以做到的,她定义了一个新版本的if:
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))Eva演示了Alyssa的程序:
(new-if (= 2 3) 0 5)
5
(new-if (= 1 1) 0 5)
0Alyssa很高兴地使用
new-if重写square-root程序:
(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))当Alyssa试图使用它计算平方根时会发生什么?解释一下。
第一法典:
(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))第二部法典:
(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))发布于 2019-06-20 17:02:48
这闻起来像是一个家庭作业问题,但是,假设您使用的是Scheme,那么考虑一下当一个普通表单(所以,不是任何一种特殊形式)像这样时会发生什么
(f a b c)评价如下:
f、a、b & c按某种未定义的顺序(可能是一次甚至一次)计算;f (即评价它的结果)的值作为一个函数应用于a、b和c的评价结果;当您使用此评估策略尝试评估better-sqrt-iter的第一个版本时,会发生什么?你可以用纸和铅笔做一些评估,看看会发生什么。
为什么这个评估规则在这里是个问题?
发布于 2019-06-20 21:52:00
我们可以使用替代模型。
(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进行同样的尝试
(better-sqrt 1)
(better-sqrt-iter 0 1.0 1)方案说,您可以按任何顺序评估过程。我从右向左选择!
(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则首先计算测试表达式,然后根据测试表达式的计算结果,只计算一个后续表达式或替代表达式,从而停止递归。
https://stackoverflow.com/questions/56690099
复制相似问题