2011-08-02 23 views
0

這裏是我的代碼:當我定義另一個函數中的函數,我得到一個「壞佈局定義」錯誤

(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),我需要它,裏面當我執行(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))) ... 

這是爲什麼?

回答

4

在一個函數中,define只允許在一個函數(或類似函數的體)的開頭,在任何情況下它們相當於一個letrec。見R5RS的this section

+0

我認爲這是答案。實際上,我一直在試驗,發現在開始定義一切時,帶有一個'letrec'聲明的代碼最終運行。謝謝! – djhaskin987

2

我不是很熟悉SCM和它的錯誤消息,但我的第一個猜測是,你會遇到letrecletrec*問題。 R5RS表示(大致)表示必須能夠在letrec表單中評估每個右手邊而不觸及任何letrec約束變量;內部定義也有同樣的限制。 (IIRC,R6RS加入letrec*形式允許這樣的參考文獻)

例如,以下是非法的:

(let() 
    (define x 1) 
    (define y (+ 1 x)) 
    y) 

因爲評估y RHS要求x值。相反,這是好的:

(let() 
    (define x 1) 
    (define f (lambda() (+ 1 x))) 
    (f)) 

也就是說,它不是作用域的問題,這是當一個變量的問題「就可以使用。」

相關問題