# # 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
``````