错误:(/)错误的参数类型:#<unspecified> Chicken Scheme平方根逼近

时间:2017-09-11 08:59:17

标签: scheme lisp sicp chicken-scheme

我正在关注麻省理工学院的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改变了我对这个问题的处理方法,但我无法弄清楚这个新错误想要暗示什么。任何修复?谢谢!

1 个答案:

答案 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