exercise 3.26 -- 追記
とりあえず、失敗した点を上げてみる
当初書いててハマったのがこれ
(define (insert! key value records) (cond ((eq? records 'empty-tree) (set! records (make-sub-tree key value '() '()))) ;;ここでハマってた ((= key (key-name records)) (set-value! records value)) ((< key (key-name records)) (if (null? (left-branch records)) (set-left! records (make-sub-tree key value '() '())) (insert! key value (left-branch records)))) ((< key (key-name records)) (if (null? (right-branch records)) (set-right! records (make-sub-tree key value '() '())) (insert! key value (right-branch records))))))
上記の奴のコメントのところがうまく働いてなかったというか、考えてみたらset!で束縛を変更しても、その変数は関数呼び出しによって新しく作られた環境の中の変数だから意味がないのだった。
わかりやすく言うと↓みたいにハマってたということ
gosh> (define (change-by-set! x) (set! x 'changed!)) change-by-set! gosh> (define a 10) a gosh> (change-by-set! a) changed! gosh> a 10 ;ありゃ?
みたいな感じ。
リストとかはポインタの集合であって、set-car!とかはポインタの先の値を変更するわけだから、上記のようにはならないと言う理解なんだがあってるのかなぁ。
gosh> (define (change-by-set-car! x) (set-car! x 'changed)) change-by-set-car! gosh> (define a (cons 1 2)) a gosh> (change-by-set-car! a) #<undef> gosh> a (changed . 2) ;;うまく行った gosh>
結局参照渡しと値渡しでハマってたって言うのかなぁ