SICP で演習 2.78 を実行しようとしていますが、関数 put と get が不明です。pretty big、racket、r5rs、mit-scheme、mzscheme などの複数の言語を試しました。SICP サポート (http://www.neilvandyke.org/sicp-plt/) もダウンロードしましたが、役に立ちませんでした。これらの機能を動作させるにはどうすればよいですか?
5 に答える
はい、私はSICPがこのようなもののために時々少し迷惑だと感じました。存在すると想定されているが実際には存在しない関数は、例を試すのを難しくします。私は自分の(get)と(put)をそのように書きました(これはGNU guileにありました):
(define global-array '())
(define (make-entry k v) (list k v))
(define (key entry) (car entry))
(define (value entry) (cadr entry))
(define (put op type item)
(define (put-helper k array)
(cond ((null? array) (list(make-entry k item)))
((equal? (key (car array)) k) array)
(else (cons (car array) (put-helper k (cdr array))))))
(set! global-array (put-helper (list op type) global-array)))
(define (get op type)
(define (get-helper k array)
(cond ((null? array) #f)
((equal? (key (car array)) k) (value (car array)))
(else (get-helper k (cdr array)))))
(get-helper (list op type) global-array))
おそらく本の後半の観点からは単純な実装ですが、かなり単純でうまく機能しました。
Eli Benderskyによるputとgetの実装があります。これらの関数は、組み込みのBasic Hash Table Operationsを使用して実装できます。これは、MIT-Scheme Release 9.1.1 で適切に動作するように、Eli のコードを修正したバージョンです。
(define *op-table* (make-hash-table))
(define (put op type proc)
(hash-table/put! *op-table* (list op type) proc))
(define (get op type)
(hash-table/get *op-table* (list op type) '()))
更新:
時間の経過とともに、上記のコードにバグが見つかりました。true空のリストは、Scheme によって条件節のように解釈されるため、正しいget実装は次のようにする必要があります。
(define (get op type)
(hash-table/get *op-table* (list op type) #f))
mit-scheme には、使用できる組み込みのグローバル テーブルがあります。
http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/The-Association-Table.html
get と put を次のように定義するだけです。
(define get 2d-get)
(define put 2d-put!)
のサブセクションCreating local tablesに3.3.3 Representing Tables、実装があります。