; a dozen lines of code
(define (make-hash hash eql? size)
(let ((hash-table (make-vector size (list))))
(case-lambda
((lookup key)
(let ((idx (modulo (hash key) size)))
(let loop ((bucket (vector-ref hash-table idx)))
(cond ((null? bucket) bucket)
((eql? (caar bucket) key) (car bucket))
(else (loop (cdr bucket)))))))
((install key value)
(let ((idx (modulo (hash key) size)))
(let loop ((bucket (vector-ref hash-table idx)) (new-bucket (list)))
(cond ((null? bucket)
(vector-set! hash-table idx (cons (cons key value) new-bucket)))
((eql? (caar bucket) key)
(vector-set! hash-table idx
(append (cons (cons key value) (cdr bucket)) new-bucket)))
(else (loop (cdr bucket) (cons (car bucket) new-bucket)))))))
(else (error 'hash-table "unrecognized command")))))
(define (string-hash str)
(do ((i 0 (+ i 1))
(h 0 (+ (* h 31) (char->integer (string-ref str i)))))
((= (string-length str) i) h)))
(define h (make-hash string-hash string=? 17))
(h 'put "alfa" 1)
(h 'put "bravo" 2)
(h 'put "charlie" 3)
(display (h 'get "alfa")) (newline)
(h 'put "alfa" 13)
(display (h 'get "alfa")) (newline)