当我在另一个函数中定义一个函数时,我得到一个“错误的位置定义”;错误
这是我的代码:
(require 'hash-table)
(define (hash-table-get htable key)
((hash-inquirer equal?) htable key))
(define (hash-table-add! htable key val)
((hash-associator equal?) htable key val))
(define (hash-table-remove! htable key)
((hash-remover equal?) htable key))
(define (find-max-chain)
(define table (make-hash-table 1000)) ; works
.
.
. ; proven working code
(define (get-chain number) (let ((chain (hash-table-get table number))) chain))
.
.
. ; more code
max-entry)
(find-max-chain)
问题是 (define (get-chain number) [...] ))
部分。当我在全局上下文中定义它和 (find-max-chain)
之外的 table
时,当我运行它时它会成功。但是当我在需要的地方定义 (get-chain)
时,当我执行 (find-max-chain) 时
我从 SCM 收到此错误:
;ERROR: "problem14-new.scm": bad placement define
; in expression: (define (get-chain! number) (let ((chain (hash-table-ge ...
; in scope:
; (update-max! table max-chain max-entry . #@define)
; () procedure find-max-chain
; defined by load: "problem14-new.scm"
;STACK TRACE
1; (#@define ((update-max! (#@lambda (entry chain) (cond ((> chai ...
2; (#@find-max-chain)
3; (#@define ((hss (#@has-suffix? #@file (#@scheme-file-suffix))) ...
这是为什么?
Here is my code:
(require 'hash-table)
(define (hash-table-get htable key)
((hash-inquirer equal?) htable key))
(define (hash-table-add! htable key val)
((hash-associator equal?) htable key val))
(define (hash-table-remove! htable key)
((hash-remover equal?) htable key))
(define (find-max-chain)
(define table (make-hash-table 1000)) ; works
.
.
. ; proven working code
(define (get-chain number) (let ((chain (hash-table-get table number))) chain))
.
.
. ; more code
max-entry)
(find-max-chain)
The problem is the (define (get-chain number) [...] ))
part. When I define it and table
outside of (find-max-chain)
in the global context, It suceeds when I run it. But when I define (get-chain)
inside of (find-max-chain)
where I need it, when I execute (find-max-chain)
I get this error from SCM:
;ERROR: "problem14-new.scm": bad placement define
; in expression: (define (get-chain! number) (let ((chain (hash-table-ge ...
; in scope:
; (update-max! table max-chain max-entry . #@define)
; () procedure find-max-chain
; defined by load: "problem14-new.scm"
;STACK TRACE
1; (#@define ((update-max! (#@lambda (entry chain) (cond ((> chai ...
2; (#@find-max-chain)
3; (#@define ((hss (#@has-suffix? #@file (#@scheme-file-suffix))) ...
Why is this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在函数内部,
define
只允许出现在函数(或类函数体)的开头,在任何情况下它们都相当于letrec
。请参阅 R5RS 的本节。Inside a function,
define
s are only allowed at the beginning of a function (or function-like body), where in any case they are equivalent to aletrec
. See this section from R5RS.我不太熟悉 SCM 及其错误消息,但我的第一个猜测是您遇到了
letrec
与letrec*
问题。 R5RS(粗略地)表示,必须能够以letrec
形式计算每个右侧,而无需触及任何letrec
绑定变量;同样的限制也适用于内部定义。 (IIRC,R6RS 添加了允许此类引用的letrec*
形式。)例如,以下内容是非法的:
因为评估
y
rhs 需要x 的值
。相比之下,这是可以的:也就是说,这不是范围界定的问题,而是变量何时“准备好使用”的问题。
I'm not very familar with SCM and its error messages, but my first guess would be that you're running afoul of the
letrec
vsletrec*
issue. R5RS says (roughly) that it must be possible to evaluate every right-hand side in aletrec
form without touching any of theletrec
bound variables; and the same restriction holds for internal definitions. (IIRC, R6RS added aletrec*
form that allows such references.)For example, the following is illegal:
because evaluating the
y
rhs requires the value ofx
. In contrast, this is okay:That is, it's not a question of scoping, it's a question of when a variable is "ready to use."