3.22 Exercise 3.22
Implementing a queue as a mutable object is not difficult. The internal procedures are almost exactly the same, except they no longer take a queue as a parameter, because they’re internal to the queue now. Additionally, the front-ptr and rear-ptr procedures are no longer needed because these are stored as internal definitions that can be accessed directly.
One thing to note is that all of the calls to dispatch return procedures – even if the procedure returned takes no argument.
(define (make-queue) (let ((front-ptr '()) (rear-ptr '())) (define (empty-queue?) (null? front-ptr)) (define (front-queue) (if (empty-queue?) (error "FRONT called with an empty queue") (car front-ptr))) (define (insert-queue! item) (let ((new-pair (cons item '()))) (cond ((empty-queue?) (set! front-ptr new-pair) (set! rear-ptr new-pair)) (else (set-cdr! rear-ptr new-pair) (set! rear-ptr new-pair))))) (define (delete-queue!) (cond ((empty-queue?) (error "DELETE! called with an empty queue")) (else (set! front-ptr (cdr front-ptr))))) (define (dispatch m) (cond ((eq? m 'empty-queue?) empty-queue?) ((eq? m 'front-queue) front-queue) ((eq? m 'insert-queue!) insert-queue!) ((eq? m 'delete-queue!) delete-queue!))) dispatch))