(define (register-alist!) (define (alist? l) (and (list? l) (every pair? l))) (define (alist-map! proc alist) (map (lambda (e) (define key (car e)) (define value (cdr e)) (cons key (proc key value))) alist)) (define (alist-filter! pred alist) (filter (lambda (e) (pred (car e) (cdr e))) alist)) (define (alist-search! alist key failure success) (define (handle-success pair) (define old-key (car pair)) (define old-value (cdr pair)) (define (update new-key new-value obj) (cond ((and (eq? old-key new-key) (eq? old-value new-value)) (values alist obj)) (else (let ((new-list (alist-cons new-key new-value (alist-delete old-key alist)))) (values new-list obj))))) (define (remove obj) (values (alist-delete old-key alist) obj)) (success old-key old-value update remove)) (define (handle-failure) (define (insert value obj) (values (alist-cons key value alist) obj)) (define (ignore obj) (values alist obj)) (failure insert ignore)) (cond ((assoc key alist) => handle-success) (else (handle-failure)))) (define (alist-size alist) (define keys (map car alist)) (define (fold-proc el set) (lset-adjoin equal? set el)) (define key-set (fold fold-proc '() keys)) (length key-set)) (define (alist-foreach proc alist) (define (proc* e) (proc (car e) (cdr e))) (for-each proc* alist)) (define (alist->alist alist) alist) (register-dictionary! 'dictionary? alist? 'dict-map! alist-map! 'dict-filter! alist-filter! 'dict-search! alist-search! 'dict-size alist-size 'dict-for-each alist-foreach 'dict->alist alist->alist))