This exercise is a little more difficult. I use a list as the key, the following diagram will help you to write correct code.
when you write code, write the basic situation first, and the write the recurision part.
(define (make-table)
(let ((local-table (list '*table*)))
(define (lookup key-list)
(define (lookup-iter key-list table)
(let ((subtable (assoc (car key-list) (cdr table))))
(if subtable
(if (null? (cdr key-list))
(cdr subtable)
(lookup-iter (cdr key-list) subtable))
false)))
(lookup-iter key-list local-table))
(define (insert! key-list value)
(define (insert-iter! key-list value table)
(let ((subtable (assoc (car key-list) (cdr table))))
(if subtable
(if (null? (cdr key-list))
(set-cdr! subtable value)
(insert-iter! (cdr key-list) value subtable))
(if (null? (cdr key-list))
(set-cdr! table
(cons (cons (car key-list) value)
(cdr table)))
(let ((new-subtable (cons (car key-list) nil)))
(set-cdr! table (cons new-subtable
(cdr table)))
(insert-iter! (cdr key-list) value new-subtable)))))
'ok)
(insert-iter! key-list value local-table))
(define (dispatch m)
(cond ((eq? m 'lookup) lookup)
((eq? m 'insert!) insert!)
(else (error "Unknown operation -- TABLE" m))))
dispatch))
(define table-1 (make-table))
(define lookup (table-1 'lookup))
(define insert! (table-1 'insert!))
;test
(insert! (list 'a 'b 'c) 1)
(lookup (list 'a 'b 'c))
(insert! '(a b d) 2)
(lookup '(a b d))
(insert! '(d) 3)
(lookup '(d))
The result of the test is as follows:'ok
1
'ok
2
'ok
3