Simple Queues

To use the bindings from this module:

(import :std/misc/queue)

make-queue

(make-queue) -> queue

Creates a new empty queue, a First-In-First-Out (FIFO) data structure similar to a list. Compared to an ordinary lists, queues allow appending elements without having to walk all to the end first.

Examples:

> (import :std/test)
> (let (q (make-queue))
    (check (queue-empty? q) => #t)
    (enqueue! q 1)
    (enqueue! q 2)
    (enqueue! q 3)
    (check (queue-length q) => 3)
    (queue->list q))
... check (queue-empty? q) is equal? to #t
... check (queue-length q) is equal? to 3
(1 2 3)

queue?

(queue? q) -> boolean

  q := queue to check

Returns #t if q is a queue, #f otherwise.

Examples:

> (let (q (make-queue))
    (enqueue! q (make-queue))
    (and (queue? q)
         (queue? (queue-peek q))
         (queue? (make-queue))))
#t

> (queue? (list 1 2 3))
#f

queue-length

(queue-length q) -> fixnum

  q := queue to check

Returns the number of elements enqueued in q.

Similar to retrieving the length of a vector, this operation is O(1), since queues always keep track of their length.

Examples:

> (let (q (make-queue))
    (enqueue! q #\a)
    (enqueue! q #\b)
    (enqueue! q #\c)
    (queue-length q))
3

> (queue-length (make-queue))
0

queue-empty?

(queue-empty? q) -> boolean

  q := queue to check

Returns #t if q has no elements enqueued, #f otherwise.

Examples:

> (queue-empty? (make-queue))
#t

> (let (q (make-queue))
    (enqueue! q (make-queue))
    (and (queue-empty? (queue-peek q))
         (queue-empty? q)))
#f

non-empty-queue?

(non-empty-queue? q) -> boolean

  q := queue to check

Returns #t if q is not empty, i.e., it has at least one element enqueued.

Equivalent to (not (queue-empty? q)).

Examples:

> (non-empty-queue? (make-queue))
#f

> (let (q (make-queue))
    (enqueue! q [])
    (non-empty-queue? q))
#t

enqueue!

(enqueue! q elem) -> unspecified

  q    := queue to push onto
  elem := element to append to q

Enqueues (pushes) elem to the end of q. Similar to set!, it's unspecified what enqueue! returns afterwards.

This operation is faster than simply appending to the end of a regular list, because queues needn't be walked first.

Examples:

> (let (q (make-queue))
    (enqueue! q 10)
    (enqueue! q 20)
    (enqueue! q 30)
    (queue->list q))
(10 20 30)

> (import :std/srfi/1 :std/test)
> (let ((q (make-queue))
        (lst (iota 10)))
    (for-each (cut enqueue! q <>) lst)
    (check-equal? (queue-length q) (length lst))
    (check-equal? (queue->list q) lst))
... check (queue-length q) is equal? to 10
... check (queue->list q) is equal? to (0 1 2 3 4 5 6 7 8 9)

enqueue-front!

(enqueue-front! q elem) -> unspecified

  q    := queue to push onto
  elem := element to enqueue to q

enqueue-front! is similar to enqueue!, but pushes elem to the front of q instead of the end. It's unspecified what will be returned.

Examples:

> (let (q (make-queue))
    (enqueue-front! q 10)
    (enqueue-front! q 20)
    (enqueue-front! q 30)
    (queue->list q))
(30 20 10)

dequeue!

(dequeue! q [default = absent-obj]) -> any | default | error

  q       := queue to pop from
  default := optional element returned when q is empty

Pops the front of q and returns that value. If q is empty and a default value is supplied, then default is returned. Otherwise an error is raised.

Examples:

> (let (q (make-queue))
    (for-each (cut enqueue! q <>) [1 2 3])
    (displayln (dequeue! q))
    (displayln (dequeue! q))
    (displayln (queue->list q))
    (displayln (dequeue! q 100))
    ;; would signal error without default value:
    (displayln (dequeue! q 100)))
1
2
(3)
3
100

queue-peek

(queue-peek q [default = absent-obj]) -> any | default | error

  q       := queue to peek front
  default := optional element returned when q is empty

Returns the front value of q without popping it from the queue like dequeue! does. If q is empty and a default value is supplied, then default is returned. Otherwise an error is raised.

Examples:

> (def q (make-queue))
> (enqueue! q #\a)
#<queue #8>
> (enqueue! q #\b)
#<queue #8>
> (queue-peek q)
#\a
> (dequeue! q)
#\a
> (queue-peek q)
#\b
> (dequeue! q)
#\b
> (queue-peek q 10)
10
> (queue-peek q)
error

queue->list

(queue->list q) -> list

  q := queue to transform into list

Returns a new list of the elements queued in q, in order.

Examples:

> (import :std/srfi/1)
> (let (q (make-queue))
    (for-each (cut enqueue! q <>) (iota 100))
    (take (queue->list q) 5))
(0 1 2 3 4)

queue

(defsyntax queue)

Queue type, for user-defined generics and destructuring.

Examples:

> (let (q (make-queue))
    (enqueue! q 1)
    (enqueue! q 'b)
    (enqueue! q #\c)
    (with ((queue elems back length) q)
      (displayln "elements: " elems ", back: " back "\nand holds " length " items")))
elements: (1 b c), back: (c)
and holds 3 items