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)
((ha开发者_StackOverflow社区sh-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?
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 a letrec
. See this section from R5RS.
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
vs letrec*
issue. R5RS says (roughly) that it must be possible to evaluate every right-hand side in a letrec
form without touching any of the letrec
bound variables; and the same restriction holds for internal definitions. (IIRC, R6RS added a letrec*
form that allows such references.)
For example, the following is illegal:
(let ()
(define x 1)
(define y (+ 1 x))
y)
because evaluating the y
rhs requires the value of x
. In contrast, this is okay:
(let ()
(define x 1)
(define f (lambda () (+ 1 x)))
(f))
That is, it's not a question of scoping, it's a question of when a variable is "ready to use."
精彩评论