Scheme 错误:(/)错误的参数类型:#<;未指明>;平方根近似

Scheme 错误:(/)错误的参数类型:#<;未指明>;平方根近似,scheme,lisp,sicp,chicken-scheme,Scheme,Lisp,Sicp,Chicken Scheme,我正在关注麻省理工学院的SICP讲座,这就是我试图通过Alexandria方法中的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)

我正在关注麻省理工学院的SICP讲座,这就是我试图通过Alexandria方法中的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))
我正在使用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     <--
错误:(/)错误的参数类型:#
通话记录:
1.a.a.scm:29:试试看
1.a.a.scm:17:goodEnough
1.a.S.scm:27:avg
1.a.SquareRootApproximation.scm:19:improve该值在其他语言中基本上是“void”。当某些过程没有任何有用的返回值时(例如,
print
将返回此值),它将用作返回值。在某些情况下,它也用作临时占位符值,例如在处理内部
定义时

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


您的意图似乎是使用作为过程输入传递的旧guess变量,因此,您可以使用
let
guess
绑定一个新值,而不是使用
define
(这应该如何表现是很好的指定),或者使用不同的名称,就像《新猜想》

我还没有学会let,我还在上第一堂课。也许新的猜测才是正确的方法。谢谢它实际上与新变量一起工作。由于在R5RS和早期的
定义
中,在
lambda
(和派生形式)中,它得到了很好的指定是
letrec
不允许在主体之前和R6RS中评估任何变量,之后是
letrec*
,允许评估已初始化的变量。当然,所有这些都不允许在同一个
lambda
中计算被任何局部
define
隐藏的变量
letrec
letrec*
允许生成递归函数,因此在闭包创建时需要存在绑定。在
表单中直接引用任何
的值是“一个错误”的意义上,这是非常明确的。然而,这基本上意味着“实现可以自由地做任何它想做的事情”。本质上,它类似于C语言中的“未定义行为”。任何“错误”都不在规范范围内,导致此类错误的程序可能会运行,也可能不会运行/编译。这是非常依赖于实现的,正如您从我的示例中看到的:MIT、Racket和Scheme48的行为与CHICKEN、Guile、Gambit和Gauche非常不同。