2011-08-02 3 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を外すと、それを実行すると成功します。私は私がそれを必要(find-max-chain)(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))) ... 

これはなぜでしょうか?

答えて

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

が、それはスコープの問題ではありません、それは変数があるときの問題だ「使用する準備ができました。」

関連する問題