;; -*- Mode: Irken -*- (define (alist-class) (define (add self k v) ;; should we check for it first? (set! self.alist (alist:entry k v self.alist))) (define (lookup self k0) (let loop ((l self.alist)) (match l with (alist:nil) -> (maybe:no) (alist:entry k1 v1 tl) -> (if (eq? k0 k1) (maybe:yes v1) (loop tl))))) (define (lookup* self k default) (match (lookup self k) with (maybe:no) -> default (maybe:yes v) -> v)) (define (get-error self k errstring) (match (lookup self k) with (maybe:no) -> (error1 errstring k) (maybe:yes v) -> v)) (define (iterate self p) (let loop ((l self.alist)) (match l with (alist:nil) -> #u (alist:entry k v tl) -> (begin (p k v) (loop tl))))) (define (map self p) (let loop ((acc '()) (l self.alist)) (match l with (alist:nil) -> (reverse acc) (alist:entry k v tl) -> (loop (list:cons (p k v) acc) tl)))) (define (keys self) (let loop ((acc '()) (l self.alist)) (match l with (alist:nil) -> (reverse acc) (alist:entry k _ tl) -> (loop (list:cons k acc) tl)))) (define (values self) (let loop ((acc '()) (l self.alist)) (match l with (alist:nil) -> (reverse acc) (alist:entry _ v tl) -> (loop (list:cons v acc) tl)))) (let ((methods {add=add get=lookup get-default=lookup* get-err=get-error iterate=iterate map=map keys=keys values=values})) ;; new method (lambda () {o=methods alist=(alist:nil)}))) (define alist-maker (alist-class))