我遵循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
。