我正在关注麻省理工学院的SICP讲座,这就是我试图通过Heron of Alexandria的方法找到一个数字的平方根逼近。这是我第一次尝试使用lisp,对不起犯了noobie错误。
(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 scheme编译器来打印它。这是输出:
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改变了我对这个问题的处理方法,但我无法弄清楚这个新错误想要暗示什么。任何修复?谢谢!
答案 0 :(得分:1)
值#<unspecified>
基本上是&#34;无效&#34;用其他语言。只要某些过程没有任何有用的返回值,它就会被用作返回值(例如,print
将返回此值)。在某些情况下,它也可用作临时占位符值,例如在处理内部define
时。
通常情况下,该语言的用户不应该看到这个临时占位符,但看起来你已经用语言打了一个奇怪的边缘情况(恭喜!这很少发生)。发生错误是因为(define guess (avg guess (/ x guess)))
过程中的improve
同时定义变量并使用该变量。执行此操作的行为并未明确指定,并且一些Scheme实现将执行CHICKEN正在执行的操作(Guile,Gauche,Gambit),而其他方案将提供更有意义的错误消息(MIT,Scheme48,Racket)。这是错误指定的原因与内部define
扩展为letrec
的事实有关,因为它允许定义相互递归的过程,但这会产生一些问题:应该发生什么对于(define a b) (define b a)
,例如?
您的意图似乎是使用旧的猜测变量作为过程的输入,因此您可以使用define
绑定let
的新值而不是guess
。 1}}(这应该如何明确指定),或者只为其使用不同的名称,例如new-guess
。