错误:(/) 错误的参数类型:#<unspecified> 鸡方案平方根近似



我遵循MIT的SICP讲座,这就是我试图找到亚历山大方法的Heron的数字的平方根近似值。这是我第一次尝试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))

我正在使用鸡肉计划编译器来打印。这是输出:

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"。只要某些过程没有任何有用的返回(例如,print将返回),它就会用作返回值。在某些情况下,它也用作临时占位符值,例如处理内部define时。

通常,该语言的用户不应该看到这个临时占位符,但看来您已经击中了语言中一个奇怪的边缘情况(恭喜!这很少发生)。发生错误是因为improve过程中的(define guess (avg guess (/ x guess)))同时定义变量并使用该变量。这样做的行为没有很好地指定,并且某些方案实现将执行Chicken在做的事情(Guile,Gauche,Gambit),而其他方案实现将提供更有意义的错误消息(MIT,Scheme48,球拍)。这是错误指定的原因与内部define扩展到letrec的事实有关,因为它允许相互递归的过程被定义,但这会引起一些问题:例如,(define a b) (define b a)会发生什么?p>您的意图似乎正在使用传递给该过程输入的旧猜测变量,因此您可以使用define,而是可以使用let来绑定guess的新值(这应该如何表现良好),或者只是使用其他名称,例如new-guess

相关内容

  • 没有找到相关文章

最新更新