本文介绍了max-lisp-eval-depth查找sqrt-iter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 03:02