(sicp?)put/getの修正

put/getには2つのバグがありました

  • リストをkeyにして正しく検索できない。
  • 失敗するとそこで終了してしまう。

'(test test)などのリストのkeyで正しく検索できない問題

リファレンスにしっかりと書いてありました。 ><
http://practical-scheme.net/gauche/man/gauche-refj_51.html

Function: make-hash-table &optional type

ハッシュテーブルを作成します。シンボルtypeはテーブルのタイプを指定します。現在、以下のようなタイプがサポートされています。 (typeが省略された場合はeq?とみなされます。)

あと、教科書の指示どおりの実装じゃなかった > get

(get )
looks up the , entry in the table and returns the item found there. If no item is found, get returns false.

検索に失敗した場合はfalse*1を返さないといけなかったみたい。

そんなわけで、前のput,getを修正

(define parent-hash (make-hash-table 'equal?))

(define (put op type item)
  (if (not (hash-table-exists? parent-hash op))
      (hash-table-put! parent-hash op (make-hash-table 'equal?)))
  (let ((child (hash-table-get parent-hash op)))
    (hash-table-put! child type item)))

(define (get op type)
  (let ((not-exist? (lambda (h arg)
                      (not (hash-table-exists? h arg)))))
    (if (not-exist? parent-hash op)
        #f
        (let ((child (hash-table-get parent-hash op)))
          (if (not-exist? child type)
              #f
              (hash-table-get child type))))))

test

(put 'test '(test test) "est-message")
(get 'test '(test test))  ; => "est-message"
(get 'lost-test '(test test))  ; => #f
(get 'test '(test test test)) ; => #f

*1:gaucheでは#f