Write a circular buffer data structure.
$ cat cirbuf.rkt #lang racket (define (circular-buffer n) (let ((elements (make-vector n)) (head 0) (tail 0) (count 0)) (lambda (cmd . args) (case (list 'quote cmd) (('mt) (= count 0)) (('dq) (if (= count 0) (raise-user-error 'circular-buffer "calling dequeue on an empty queue") (let ((e (vector-ref elements head))) (set! count (- count 1)) (set! head (remainder (+ head 1) n)) e))) (('nq) (if (= count n) (raise-user-error 'circular-buffer "calling enqueue on a full queue") (begin (vector-set! elements tail (car args)) (set! count (+ count 1)) (set! tail (remainder (+ tail 1) n))))) (else (raise-user-error 'circular-buffer "Don't recognize ~a as a command" cmd)))))) (require rackunit "utl.rkt") (let* ((n 10) (l (permuted-iota n)) (cb (circular-buffer n))) (let loop ((l l)) (unless (null? l) (cb 'nq (car l)) (loop (cdr l)))) (check-eq? (cb 'mt) #f) (let loop ((l l)) (unless (null? l) (check-eq? (cb 'dq) (car l)) (loop (cdr l)))) (check-eq? (cb 'mt) #t)) $ racket cirbuf.rkt $