;; A Queue is a Abstract Value ;; Internally, a Queue is a (HiddenToken -> Listof[SchemeValue]), ;; where HiddenToken is a singleton that nothing outside ;; of { empty, snoc, isEmpty, head, tail } knows about. (define empty 'defined-below) (define snoc 'defined-below) (define isEmpty 'defined-below) (define head 'defined-below) (define tail 'defined-below) (let ((hidden-token (cons 'unique 'and-hidden))) (let ((concrete->abstract ;; Listof[SchemeValue] -> Queue (lambda (lst) (let ((an-abstract-queue (lambda (token) (if (eq? token hidden-token) lst (error 'unauthorized-attempt-to-access-queue-internals!))))) an-abstract-queue))) (abstract->concrete ;; Queue -> Listof[SchemeValue] (lambda (q) (q hidden-token)))) (set! empty (lambda () (concrete->abstract '()))) (set! snoc (lambda (q v) (concrete->abstract (append (abstract->concrete q) (list v))))) (set! isEmpty (lambda (q) (null? (abstract->concrete q)))) (set! head (lambda (q) (car (abstract->concrete q)))) (set! tail (lambda (q) (concrete->abstract (cdr (abstract->concrete q))))) ))