Error: (/) bad argument type: #<unspecified> Chicken Scheme Square root approximation

Error: (/) bad argument type: #<unspecified> Chicken Scheme Square root approximation

我正在听麻省理工学院的 SICP 讲座,这就是我试图通过 Heron of Alexandria 的方法求一个数的平方根近似值。这是我第一次尝试 lisp,很抱歉犯了新手错误。

(define guess 1)

(define (avg a b)
  (/ (+ a b) 2))

(define (try guess x)
  (if (goodEnough guess x)
      guess
      (improve guess x)))

(define (improve guess x)
  (define guess (avg guess (/ x guess)))
  (try guess x)
  )

(define (goodEnough guess x)
  (= guess (avg guess (/ x guess))))

(print (try 1 25))

我正在使用 Chicken 方案编译器来打印它。这是输出:

Error: (/) bad argument type: #<unspecified>

    Call history:

    1.a.SquareRootApproximation.scm:29: try   
    1.a.SquareRootApproximation.scm:17: goodEnough    
    1.a.SquareRootApproximation.scm:27: avg   
    1.a.SquareRootApproximation.scm:19: improve     <--

更新: 我已经使用更抽象的 lisp 改变了我解决这个问题的方法,但我无法弄清楚这个新错误想要暗示什么。任何修复?谢谢!

价值#<unspecified>在其他语言中基本上是"void"。只要某些过程对 return 没有任何用处,它就用作 return 值(例如,print 将 return this)。它在某些情况下也用作临时占位符值,例如在处理内部 define 时。

通常情况下,该语言的用户不应看到此临时占位符,但您似乎遇到了该语言中的奇怪边缘情况(恭喜!这种情况很少发生)。发生错误是因为 improve 过程中的 (define guess (avg guess (/ x guess))) 同时定义了一个变量并使用了该变量。这样做的行为没有明确规定,一些 Scheme 实现会做 CHICKEN 正在做的事情(Guile、Gauche、Gambit),而其他人会给出更有意义的错误消息(MIT、Scheme48、Racket)。这是错误指定的原因与内部 define 扩展到 letrec 的事实有关,因为它允许定义相互递归过程,但这会产生一些问题:应该发生什么(define a b) (define b a),例如?

您的意图似乎是使用作为输入传递给过程的旧猜测变量,因此您可以使用 let 来为 [=20= 绑定一个新值,而不是使用 define ](它应该如何表现是明确指定的),或者只是使用不同的名称,比如 new-guess.