;; An entry holds a key/value pair ;; for use in Dictionaries. ;; (define-struct entry (key value)) ;; have-key? key entry --> boolean ;; Returns whether the key is the same as that of the entry. (define (have-key? key entry) (equal? key (entry-key entry))) ;;;;;;;;;;;;;;;;;; ;; Global list-of-entries: ;; (define contents empty) ;; add!: ANY ANY --> list-of-entries ;; SIDE-EFFECT: change the contents. ;; We return (the updated) contents. ;; (define (add! k val) (begin (set! contents (cons (make-entry k val) contents)) contents)) ; Note: what if k already occurs in contents? ; hmm... ; One alternative to having a list with the same key twice would be ; changing the old entry. ; (local {[old-entry (lookup k)]} ; (cond [(entry? old-entry) (set-entry-value! old-entry val)] ; [(boolean? old-entry) (set! contents ...)])) ; As above. ; This relies on the fact that only our functions deal with entries, ; and so we know that there isn't other sharing going on. ; (Is this 100% true?... Not if we return entries to our users!) ;; lookup: key --> entry or false ;; Does the key occur inside "contents"? ;; If so, return that entry, else return the sentinel false. ;; (define (lookup key) (local [;; helper: list-of-entries --> entry or false ;; Does the key occur inside "entries"? ;; If so, return that entry, else return false. ;; (define (helper entries) (cond [(empty? entries) false] [(cons? entries) (cond [(have-key? key (first entries)) (first entries)] [else (helper (rest entries))])]))] (helper contents)) ;;;;;; Tests (lookup 'gesundheit) (add! 'gesundheit 'health) (lookup 'gesundheit) (add! 'wissenschaft 'science) (lookup 'gesundheit) (add! 'informatik 'computer-science) (lookup 'wissenschaft) (lookup 'gesundheit) (lookup 'gymnasium)