问题描述
我正在研究SICP的练习1.6,该练习重写了演示案例
I am working on SICP's exercise 1.6 which rewrite the demonstration case
#+begin_src emacs-lisp :session sicp :results output
(defun sqrt(x)
(sqrt-iter 1.0 x))
(defun sqrt-iter(guess x)
(if (good-enough-p guess x)
guess
(sqrt-iter (improve guess x)
x)))
(defun good-enough-p(guess x)
(< (abs (- (square guess) x)) 0.001))
(defun improve(guess x)
(average guess (/ x guess)))
(defun average(x y)
(/ (+ x y) 2))
#+end_src
它可以正常工作并获取输出
It works and get the output
#+begin_src emacs-lisp :session sicp :lexical t :results output
(print (sqrt 11))
(print (sqrt (+ 100 37)))
(print (sqrt (+ (sqrt 2) (sqrt 3))))
#+end_src
#+RESULTS:
:
: 3.3166248052315686
:
: 11.704699917758145
:
: 1.7739279023207892
因此,进入练习1.6并用cond
Thus come to Exercise 1.6 which rewrite it with cond
#+begin_src emacs-lisp :session sicp :lexical t
(defun sqrt-iter-cond(guess x)
(cond ((good-enough-p guess x) guess)
(t (sqrt-iter-cond (improve guess x) x))
)
)
(sqrt-iter-cond 1 10)
#+end_src
它报告错误:
ob-async-org-babel-execute-src-block: Lisp nesting exceeds ‘max-lisp-eval-depth’
在阅读了各种解释之后,我陷入了更多的困惑,甚至产生了隐含的恐惧,即害怕使用cond
后记.因为这显然是逻辑上正确的.
After reading various explanations, more confusions I immersed in and even raise an implicit fear to employ cond
afterwords. Because It seem clearly logical correct.
请给我任何提示吗?
推荐答案
cond
版本没有任何问题,从一个空的缓冲区开始,然后尝试一下,它将起作用:
There's nothing wrong with the cond
version, start with an empty buffer and try this, it'll work:
(defun sqrt (x)
(sqrt-iter-cond 1.0 x))
(defun sqrt-iter-cond (guess x)
(cond ((good-enough-p guess x) guess)
(t (sqrt-iter-cond (improve guess x) x))))
(defun good-enough-p (guess x)
(< (abs (- (square guess) x)) 0.001))
(defun improve (guess x)
(average guess (/ x guess)))
(defun average(x y)
(/ (+ x y) 2))
(print (sqrt 11))
=> 3.3166247903554
但是练习不是要用cond
重写过程,它应该告诉您不能使用过程编写自己的if
版本,并且需要具有特殊评估规则的特殊形式-因为程序的评估规则将同时评估后续零件和替代零件,所以这是行不通的!看这个简单的例子,看看我的意思:
But the exercise is not about rewriting the procedure with cond
, it's supposed to show you that you can't write your own version of if
using procedures, and that you need a special form with special evaluation rules - because evaluation rules of procedures will evaluate both the consequent and the alternative parts at the same time, and that won't work! Look at this simple example to see what I mean:
(if t 'ok (/ 1 0))
以上内容将返回'ok
,即使在那里被零除:该部分从未执行过.但是,如果我们尝试使用作为常规过程实现的自己的if
来执行此操作,则它将失败,并且除以零错误:
The above will return 'ok
, even though there's a division by zero there: that part never got executed. But if we try to do it with our own if
implemented as a normal procedure, it'll fail with a division by zero error:
(defun my-if (condition consequent alternative)
(cond (condition consequent)
(t alternative)))
(my-if t 'ok (/ 1 0))
现在返回您的代码并尝试它,当然它也会失败,但是这次出现了无限递归错误(这就是"Lisp嵌套超出'max-lisp-eval-depth'"消息的含义) :
Now go back to your code and try it, of course it'll also fail, but this time with an infinite recursion error (that's what the "Lisp nesting exceeds ‘max-lisp-eval-depth’" message means):
(defun sqrt-iter (guess x)
(my-if (good-enough-p guess x)
guess
(sqrt-iter (improve guess x)
x)))
这篇关于max-lisp-eval-depth查找sqrt-iter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!