Question

I am trying to do exercise 2.78 in SICP, but the functions put and get are unknown. I have tried multiple languages, like pretty big, racket, r5rs, mit-scheme, mzscheme, etc. I even downloaded the SICP support (http://www.neilvandyke.org/sicp-plt/), to no avail. How can I get these functions to work?

Was it helpful?

Solution

Yes, I found SICP a little annoying sometimes because of stuff like this. Functions that are assumed to exist but don't actually exist make it harder to try to the examples. I wrote my own (get) and (put) like so (this was in 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))

Probably a naive implementation from the perspective of later in the book, but fairly simple and worked fine.

OTHER TIPS

There is an implementation of put and get by Eli Bendersky. These functions could be implemented using builtin Basic Hash Table Operations. Here is my modified version of Eli's code to work properly with MIT-Scheme Release 9.1.1.

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

UPDATED:

I've found bug with above mentioned code after time. Empty lists are interpreted as true in conditional clauses by Scheme, so correct get implementation should be following:

(define (get op type)
  (hash-table/get *op-table* (list op type) #f))

If you use Racket programming language please use these:

(define *op-table* (make-hash))

(define (put op type proc)
  (hash-set! *op-table* (list op type) proc))

(define (get op type)
  (hash-ref *op-table* (list op type) '()))

In subsection Creating local tables of 3.3.3 Representing Tables, there is an implementation.

mit-scheme has a built-in global table that you can use.

http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/The-Association-Table.html

simply define get and put to:

(define get 2d-get)
(define put 2d-put!)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top