Syntax 方案/球拍-未定义的功能;在初始化之前不能使用

Syntax 方案/球拍-未定义的功能;在初始化之前不能使用,syntax,scheme,racket,sicp,Syntax,Scheme,Racket,Sicp,目前正在进行SICP,在第一章接近尾声时,他们要求您用 pi/4=(2*4*4*6*6*8*…)/(3*3*5*5*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)))) 及

目前正在进行SICP,在第一章接近尾声时,他们要求您用
pi/4=(2*4*4*6*6*8*…)/(3*3*5*5*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))))

在DrRacket中运行此代码时,出现以下错误:
num prod:未定义;无法在初始化之前使用
,即使我在使用num prod之前初始化了几行


我在语法上做错了什么

这是谷歌对这个问题的最佳搜索结果之一,所以我想我应该添加一些更详细的信息:

在大多数方案实现(如R5R)中,无法保证解析定义的顺序。换句话说,它们不是按顺序解析的。是的,您在前面几行定义了
num prod
,但完全有可能是先编译
num
,因此出现错误


在Racket中,lambda被编译成
letrec*
操作符,而不是
letrec
,这意味着可以保证顺序解析。这就是为什么改变语言很有帮助。

这是谷歌对这个问题的最佳搜索结果之一,所以我想我应该补充一些细节:

在大多数方案实现(如R5R)中,无法保证解析定义的顺序。换句话说,它们不是按顺序解析的。是的,您在前面几行定义了
num prod
,但完全有可能是先编译
num
,因此出现错误


在Racket中,lambda被编译成
letrec*
操作符,而不是
letrec
,这意味着可以保证顺序解析。这就是为什么改变语言会有帮助。

因为我目前也在经历SICP并遇到同样的错误,我想我应该提到我认为的解决方案,因为问题在
let
lambda
之前的部分

第一章脚注28简要提到了这一错误:

在过程体中,嵌入的定义必须放在第一位。管理层不是 负责运行混淆了定义和定义的程序的后果 使用

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,并且遇到了相同的错误,我想我应该提到我认为的预期解决方案,因为问题在
let
lambda
之前的部分

第一章脚注28简要提到了这一错误:

在过程体中,嵌入的定义必须放在第一位。管理层不是 负责运行混淆了定义和定义的程序的后果 使用

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)))

只要我添加
(define inc add1)
,我就可以很好地工作。您使用的是REPL还是definitions区域?我不确定两者之间的区别,但我使用的是编辑器的顶部。。。下面是它的外观:。旁注,我确实有
(define(inc x)(+x1))
代码,所以我有理由肯定这不是问题的一部分。小小的突破!我四处询问,发现解决问题的方法是使用
#lang racket
而不是
#lang sicp
。。。我真的不知道为什么这会改变任何事情,但任何见解都是受欢迎的!它可能将所有内部定义分组为一个
letrec
,从而导致错误。这意味着前3个定义有一个
letrec
,接下来两个定义有一个
let
。只是永远不要使用内部
define
s,这是一种毫无意义的方便语法,不管怎样,真正的问题是
let
/
letrec
。我一添加
(define inc add1)
,效果就很好了。您使用的是REPL还是definitions区域?我不确定两者之间的区别,但我使用的是编辑器的顶部。。。下面是它的外观:。旁注,我确实有
(define(inc x)(+x1))
代码,所以我有理由肯定这不是问题的一部分。小小的突破!我四处询问,发现解决问题的方法是使用
#lang racket
而不是
#lang sicp
。。。我真的不知道为什么这会改变任何事情,但任何见解都是受欢迎的!它可能将所有内部定义分组为一个
letrec
,从而导致错误。这意味着前3个定义有一个
letrec
,接下来两个定义有一个
let
。只是永远不要使用内部的
define
s,这是一个毫无意义的方便语法,不管怎样,真正的问题是
let
/
letrec
。一个更干净的解决方案是
(define(num n)(product num prod 1 inc n))
(define(denom n)(product denom prod 1 inc n))
,然后
(*4(/(num n)(denom n)))
。看起来更干净