# (lispkit gvector)

This library defines an API for *growable vectors*. Just like regular vectors, *growable vectors* are heterogeneous sequences of elements which are indexed by a range of integers. Unlike for regular vectors, the length of a *growable vector* is not fixed. Growable vectors may expand or shrink in length. Nevertheless, growable vectors are fully compatible to regular vectors and all operations from library `(lispkit vector)` may also be used in combination with growable vectors. The main significance of library `(lispkit gvector)` is in providing functions to construct growable vectors. Growable vectors are always *mutable* by design.

Just like for vectors with a fixed length, the valid indexes of a growable vector are the exact, non-negative integers less than the length of the vector. The first element in a vector is indexed by zero, and the last element is indexed by one less than the length of the growable vector.

Two growable vectors are `equal?` if they have the same length, and if the values in corresponding slots of the vectors are `equal?`. A growable vector is never `equal?` a regular vector of fixed length.

Growable vectors are written using the notation `#g(obj ...)`. For example, a growable vector of initial length 3 containing the number one as element 0, the list (8 16 32) as element 1, and the string "Scheme" as element 2 can be written as follows: `#g(1 (8 16 32) "Scheme")`.

Growable vector constants are self-evaluating, so they do not need to be quoted in programs.

## Predicates

**(gvector?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns `#t` if *obj* is a growable vector; otherwise returns `#f`.

**(gvector-empty?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns `#t` if *obj* is a growable vector of length zero; otherwise returns `#f`.

## Constructors

**(make-gvector)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(make-gvector&#x20;*****c*****)**

Returns a newly allocated growable vector of capacity *c*. The capacity is used to pre-allocate space for up to *c* elements.

**(gvector&#x20;*****obj ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated growable vector whose elements contain the given arguments.

```scheme
(gvector ’a ’b ’c)  ⇒  #g(a b c)
```

**(list->gvector&#x20;*****list*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `list->gvector` procedure returns a newly created growable vector initialized to the elements of the list *list* in the order of the list.

```scheme
(list->gvector ’(a b c))  ⇒  #g(a b c)
```

**(vector->gvector&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated growable vector initialized to the elements of the vector *vector* in the order of *vector*.

**(gvector-copy&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(gvector-copy&#x20;*****vector start*****)**\
\&#xNAN;**(gvector-copy&#x20;*****vector start end*****)**

Returns a newly allocated copy of the elements of the given growable vector between *start* and *end*, but excluding the element at index *end*. The elements of the new vector are the same (in the sense of `eqv?`) as the elements of the old.

**(gvector-append&#x20;*****vector ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated growable vector whose elements are the concatenation of the elements of the given vectors.

```scheme
(gvector-append #(a b c) #g(d e f))  ⇒  #g(a b c d e f)
```

**(gvector-concatenate&#x20;*****vector xs*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated growable vector whose elements are the concatenation of the elements of the vectors in *xs*. *xs* is a proper list of vectors.

```scheme
(gvector-concatenate '(#g(a b c) #(d) #g(e f)))  ⇒  #g(a b c d e f)
```

**(gvector-map&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Constructs a new growable vector of the shortest size of the vector arguments *vector1*, *vector2*, etc. Each element at index *i* of the new vector is mapped from the old vectors by `(f (vector-ref vector1 i) (vector-ref vector2 i) ...)`. The dynamic order of the application of f is unspecified.

```scheme
(gvector-map + #(1 2 3 4 5) #g(10 20 30 40))  ⇒  #g(11 22 33 44)
```

**(gvector-map/index&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Constructs a new growable vector of the shortest size of the vector arguments *vector1*, *vector2*, etc. Each element at index *i* of the new vector is mapped from the old vectors by `(f i (vector-ref vector1 i) (vector-ref vector2 i) ...)`. The dynamic order of the application of f is unspecified.

```scheme
(gvector-map/index (lambda (i x y) (cons i (+ x y))) #g(1 2 3) #(10 20 30))  ⇒  #g((0 . 11) (1 . 22) (2 . 33))
```

## Iterating over vector elements

**(gvector-for-each&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

`gvector-for-each` implements a simple vector iterator: it applies *f* to the corresponding list of parallel elements from vectors *vector1 vector2 ...* in the range *\[0, length)*, where *length* is the length of the smallest vector argument passed. In contrast with `gvector-map`, *f* is reliably applied to each subsequent element, starting at index 0, in the vectors.

```scheme
(gvector-for-each (lambda (x) (display x) (newline)) 
                  #g("foo" "bar" "baz" "quux" "zot"))
⇒
foo
bar
baz
quux
zot
```

**(gvector-for-each/index&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

`gvector-for-each/index` implements a simple vector iterator: it applies *f* to the index *i* and the corresponding list of parallel elements from *vector1 vector2 ...* in the range *\[0, length)*, where *length* is the length of the smallest vector argument passed. The only difference to `gvector-for-each` is that `gvector-for-each/index` always passes the current index as the first argument of *f* in addition to the elements from the vectors *vector1 vector2 ...*.

```scheme
(gvector-for-each/index
  (lambda (i x) (display i)(display ": ")(display x)(newline))
  #g("foo" "bar" "baz" "quux" "zot"))
⇒
0: foo
1: bar
2: baz
3: quux
4: zot
```

## Managing vector state

**(gvector-length&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns the number of elements in growable vector *vector* as an exact integer.

**(gvector-ref&#x20;*****vector k*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `gvector-ref` procedure returns the contents of element *k* of *vector*. It is an error if *k* is not a valid index of *vector* or if *vector* is not a growable vector.

```scheme
(gvector-ref ’#g(1 1 2 3 5 8 13 21) 5) ⇒  8
(gvector-ref ’#g(1 1 2 3 5 8 13 21) (exact (round (* 2 (acos -1)))))  ⇒  13
```

**(gvector-set!&#x20;*****vector k obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `vector-set!` procedure stores *obj* in element *k* of growable vector *vector*. It is an error if *k* is not a valid index of *vector* or if *vector* is not a growable vector.

```scheme
(let ((vec (gvector 0 '(2 2 2 2) "Anna")))
  (gvector-set! vec 1 '("Sue" "Sue"))
  vec)
  ⇒  #g(0 ("Sue" "Sue") "Anna")
```

**(gvector-add!&#x20;*****vector obj ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Appends the values *obj*, ... to growable vector *vector*. This increases the length of the growable vector by the number of *obj* arguments.

```scheme
(let ((vec (gvector 0 '(2 2 2 2) "Anna")))
  (gvector-add! vec "Micha")
  vec)
  ⇒  #g(0 (2 2 2 2) "Anna" "Micha")
```

**(gvector-insert!&#x20;*****vector k obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Inserts the value *obj* into growable vector *vector* at index *k*. This increases the length of the growable vector by one.

```scheme
(let ((vec (gvector 0 '(2 2 2 2) "Anna")))
  (gvector-insert! vec 1 "Micha")
  vec)
  ⇒  #g(0 "Micha" (2 2 2 2) "Anna")
```

**(gvector-remove!&#x20;*****vector k*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Removes the element at index *k* from growable vector *vector*. This decreases the length of the growable vector by one.

```scheme
(let ((vec (gvector 0 '(2 2 2 2) "Anna")))
  (gvector-remove! vec 1)
  vec)
  ⇒  #g(0 "Anna")
```

**(gvector-remove-last!&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Removes the last element of the growable vector *vector*. This decreases the length of the growable vector by one.

```scheme
(let ((vec (gvector 0 '(2 2 2 2) "Anna")))
  (gvector-remove-last! vec)
  vec)
  ⇒  #g(0 (2 2 2 2))
```

## Destructive growable vector operations

Procedures which operate only on a part of a growable vector specify the applicable range in terms of an index interval \[*start*; *end*\[; i.e. the *end* index is always exclusive.

**(gvector-copy!&#x20;*****to at from*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(gvector-copy!&#x20;*****to at from start*****)**\
\&#xNAN;**(gvector-copy!&#x20;*****to at from start end*****)**

Copies the elements of vector *from* between *start* and *end* to growable vector *to*, starting at *at*. The order in which elements are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary vector and then into the destination. *start* defaults to 0 and *end* defaults to the length of *vector*.

It is an error if *at* is less than zero or greater than the length of *to*. It is also an error if `(- (gvector-length to) at)` is less than `(- end start)`.

```scheme
(define a (vector 1 2 3 4 5))
(define b (gvector 10 20 30 40 50))
(gvector-copy! b 1 a 0 2)
b  ⇒  #g(10 1 2 40 50)
```

**(gvector-append!&#x20;*****vector v1 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Appends the elements of the vectors *v1 ...* to the growable vector *vector* in the given order.

**(gvector-reverse!&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(gvector-reverse!&#x20;*****vector start*****)**\
\&#xNAN;**(gvector-reverse!&#x20;*****vector start end*****)**

Procedure `gvector-reverse!` destructively reverses the contents of growable *vector* between *start* and *end*. *start* defaults to 0 and *end* defaults to the length of *vector*.

```scheme
(define a (gvector 1 2 3 4 5))
(vector-reverse! a)
a  ⇒  #g(5 4 3 2 1)
```

**(gvector-sort!&#x20;*****pred vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Procedure `gvector-sort!` destructively sorts the elements of growable vector *vector* using the "less than" predicate *pred*.

```scheme
(define a (gvector 7 4 9 1 2 8 5))
(gvector-sort! < a)
a  ⇒  #g(1 2 4 5 7 8 9)
```

**(gvector-map!&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Similar to `gvector-map` which maps the various elements into a new vector via function *f*, procedure `gvector-map!` destructively inserts the mapped elements into growable vector *vector1*. The dynamic order in which *f* gets applied to the elements is unspecified.

```scheme
(define a (gvector 1 2 3 4))
(gvector-map! + a #(10 20 30))
a  ⇒  #g(11 22 33 4)
```

**(gvector-map/index!&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Similar to `gvector-map/index` which maps the various elements together with their index into a new vector via function *f*, procedure `gvector-map/index!` destructively inserts the mapped elements into growable vector *vector1*. The dynamic order in which *f* gets applied to the elements is unspecified.

```scheme
(define a #g(1 2 3 4))
(gvector-map/index! (lambda (i x y) (cons i (+ x y))) a #(10 20 30))
a  ⇒  #g((0 . 11) (1 . 22) (2 . 33) 4)
```

## Converting growable vectors

**(gvector->list&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(gvector->list&#x20;*****vector start*****)**\
\&#xNAN;**(gvector->list&#x20;*****vector start end*****)**

The `gvector->list` procedure returns a newly allocated list of the objects contained in the elements of growable *vector* between *start* and *end* in the same order as in *vector*.

```scheme
(gvector->list ’#g(dah dah didah))  ⇒  (dah dah didah)
(gvector->list ’#g(dah dah didah) 1 2)  ⇒  (dah)
```

**(gvector->vector&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(gvector->vector&#x20;*****vector start*****)**\
\&#xNAN;**(gvector->vector&#x20;*****vector start end*****)**

The `gvector->list` procedure returns a newly allocated list of the objects contained in the elements of growable vector *vector* between *start* and *end* in the same order as in *vector*.

```scheme
(gvector->list ’#(dah dah didah))  ⇒  error since the argument is not a gvector
(gvector->list ’#g(dah dah didah) 1 2)  ⇒  (dah)
```
