Here is the implementation of QUEUE as a procedure with local state.
;;;QUEUE as a procedure with local state
(define (make-queue)
(let ((front-ptr nil)
(rear-ptr nil))
(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!)
((eq? m 'print-queue) print-queue)
(else (error "Undefined operation -- MAKE-QUEUE" m))))
(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 nil)))
(if (empty-queue?)
(begin (set! front-ptr new-pair)
(set! rear-ptr new-pair))
(begin (set-cdr! rear-ptr new-pair)
(set! rear-ptr new-pair)))))
(define (delete-queue!)
(if (empty-queue?)
(error "DELETE called with an empty queue")
(set! front-ptr (cdr front-ptr))))
(define (print-queue)
(display front-ptr))
dispatch))
;;;QUEUE OPERATIONS
(define (empty-queue? queue)
((queue 'empty-queue?)))
(define (front-queue queue)
((queue 'front-queue)))
(define (insert-queue! queue item)
((queue 'insert-queue!) item)
queue)
(define (delete-queue! queue)
((queue 'delete-queue!))
queue)
(define (print-queue queue)
((queue 'print-queue)))
The test code is as follows:
;;;TEST
(define q1 (make-queue))
(print-queue (insert-queue! q1 'a))
(newline)
(print-queue (insert-queue! q1 'b))
(newline)
(print-queue (delete-queue! q1))
(newline)
(print-queue (delete-queue! q1))
(newline)
(empty-queue? q1)
And the result of the test is:
(a)
(a b)
(b)
()
#t