Scheme/Racket - 未定义函数;初始化前不能使用
Scheme/Racket - Undefined Function; Cannot use before initialization
目前正在学习 SICP,在第一章快结束时,他们要求您为 pi 编写一个值,其中
pi/4 = (2 * 4 * 4 * 6 * 6 * 8 * ...) / (3 * 3 * 5 * 5 * 7 * 7 *..)
我定义了以下函数:
;Term and Next are both functions, a and b are the range of the product
(define (product term a next b)
(if (> a b) 1
(* (term a) (product term (next a) next b))))
和
(define (pi-approx n)
(define (square x) (* x x))
(define (num-prod ind) (* (* 2 ind) (* 2 (+ ind 1)))) ; calculates the product in the numerator for a certain term
(define (denom-prod ind) (square (+ (* ind 2 ) 1))) ;Denominator product at index ind
(define num (product num-prod 1 inc n))
(define denom (product denom-prod 1 inc n))
(* 4 (/ num denom))) ;;Resulting value
当我在 DrRacket 中 运行 这段代码时,出现以下错误:
num-prod: Undefined; Cannot use before initialization
,即使我在使用前几行初始化了 num-prod。
我在语法上做错了什么?
这是该问题的前 Google 个结果之一,所以我想添加更多细节:
在大多数 Scheme 实现中(例如 R5RS),无法保证定义的解析顺序。换句话说,它们不是按顺序解析的。是的,您之前定义了 num-prod
几行,但是 num
完全有可能首先编译,因此出现错误。
在 Racket 中,lambda 被编译为 letrec*
运算符而不是 letrec
,这意味着 是 顺序解析的保证。这就是为什么改变语言有帮助。
因为我目前也在通过 SICP 和 运行 进入同样的错误,我想我会提到我认为是预期的解决方案,因为问题在 [=11= 之前的部分] 和 lambda
.
这个错误在第一章脚注28中有简要提及:
Embedded definitions must come first in a procedure body. The management is not
responsible for the consequences of running programs that intertwine definition and
use.
num-prod
正在另一个定义中使用,因此该程序实际上是将定义和使用交织在一起,即使看起来定义都在主体之前。
可能的解决方案(没有 let
和 lambda
)是避免定义 num
和 denom
,将它们替换为 product
表达式,或者将 num
定义为带参数的函数,并将 num-prod
作为函数体中的参数:
(define (num terms) (product terms 1 inc n))
(define (denom terms) (product terms 1 inc n))
(* 4 (/ (num num-prod) (denom denom-prod)))
目前正在学习 SICP,在第一章快结束时,他们要求您为 pi 编写一个值,其中
pi/4 = (2 * 4 * 4 * 6 * 6 * 8 * ...) / (3 * 3 * 5 * 5 * 7 * 7 *..)
我定义了以下函数:
;Term and Next are both functions, a and b are the range of the product
(define (product term a next b)
(if (> a b) 1
(* (term a) (product term (next a) next b))))
和
(define (pi-approx n)
(define (square x) (* x x))
(define (num-prod ind) (* (* 2 ind) (* 2 (+ ind 1)))) ; calculates the product in the numerator for a certain term
(define (denom-prod ind) (square (+ (* ind 2 ) 1))) ;Denominator product at index ind
(define num (product num-prod 1 inc n))
(define denom (product denom-prod 1 inc n))
(* 4 (/ num denom))) ;;Resulting value
当我在 DrRacket 中 运行 这段代码时,出现以下错误:
num-prod: Undefined; Cannot use before initialization
,即使我在使用前几行初始化了 num-prod。
我在语法上做错了什么?
这是该问题的前 Google 个结果之一,所以我想添加更多细节:
在大多数 Scheme 实现中(例如 R5RS),无法保证定义的解析顺序。换句话说,它们不是按顺序解析的。是的,您之前定义了 num-prod
几行,但是 num
完全有可能首先编译,因此出现错误。
在 Racket 中,lambda 被编译为 letrec*
运算符而不是 letrec
,这意味着 是 顺序解析的保证。这就是为什么改变语言有帮助。
因为我目前也在通过 SICP 和 运行 进入同样的错误,我想我会提到我认为是预期的解决方案,因为问题在 [=11= 之前的部分] 和 lambda
.
这个错误在第一章脚注28中有简要提及:
Embedded definitions must come first in a procedure body. The management is not responsible for the consequences of running programs that intertwine definition and use.
num-prod
正在另一个定义中使用,因此该程序实际上是将定义和使用交织在一起,即使看起来定义都在主体之前。
可能的解决方案(没有 let
和 lambda
)是避免定义 num
和 denom
,将它们替换为 product
表达式,或者将 num
定义为带参数的函数,并将 num-prod
作为函数体中的参数:
(define (num terms) (product terms 1 inc n))
(define (denom terms) (product terms 1 inc n))
(* 4 (/ (num num-prod) (denom denom-prod)))