# (lispkit vector)

Vectors are heterogeneous data structures whose elements are indexed by a range of integers. A vector typically occupies less space than a list of the same length, and a randomly chosen element can be accessed in constant time vs. linear time for lists.

The *length* of a vector is the number of elements that it contains. This number is a non-negative integer that is fixed when the vector is created. The valid indexes of a 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 vector.

Two vectors are `equal?` if they have the same length, and if the values in corresponding slots of the vectors are `equal?`.

A vector can be *mutable* or *immutable*. Trying to change the state of an *immutable vector*, e.g. via `vector-set!` will result in an error being raised.

Vectors are written using the notation `#(obj ...)`. For example, a vector of length 3 containing the number zero in element 0, the list (1 2 3 4) in element 1, and the string "Lisp" in element 2 can be written as follows: `#(0 (1 2 3 4) "Lisp")`.

Vector constants are self-evaluating, so they do not need to be quoted in programs. Vector constants, i.e. vectors created with a vector literal, are *immutable*.

LispKit also supports *growable vectors* via library `(lispkit gvector)`. As opposed to regular vectors, a growable vector does not have a fixed size and supports adding and removing elements. While a growable vector does not satisfay the `vector?` predicate, this library also accepts growable vectors as parameters whenever a vector is expected. Use predicate `mutable-vector?` for determining whether a vector is either a regular mutable vector or a growable vector.

## Predicates

**(vector?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is a regular vector; otherwise returns `#f`. This function returns `#f` for growable vectors; see library `(lispkit gvector)`.

**(mutable-vector?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is either a mutable regular vector or a growable vector (see library `(lispkit gvector)`); otherwise returns `#f`.

**(immutable-vector?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is an immutable vector; otherwise returns `#f`.

**(vector=&#x20;*****eql vector ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Procedure `vector=` is a generic comparator for vectors. Vectors *a* and *b* are considered equal by `vector=` if their lengths are the same, and for each respective elements *ai* and *bi*, `(eql ai bi)` evaluates to true. *eql* is always applied to two arguments.

If there are only zero or one vector argument, `#t` is automatically returned. The dynamic order in which comparisons of elements and of vectors are performed is unspecified.

```scheme
(vector= eq? #(a b c d) #(a b c d))  ⇒  #t 
(vector= eq? #(a b c d) #(a b d c))  ⇒  #f 
(vector= = #(1 2 3 4 5) #(1 2 3 4))  ⇒  #f 
(vector= = #(1 2 3 4) #(1.0 2.0 3.0 4.0))  ⇒  #t 
(vector= eq?) ⇒  #t 
(vector= eq? '#(a))  ⇒  #t 
```

## Constructors

**(make-vector&#x20;*****k*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(make-vector&#x20;*****k fill*****)**

Returns a newly allocated vector of *k* elements. If a second argument is given, then each element is initialized to *fill*. Otherwise the initial contents of each element is unspecified.

**(vector&#x20;*****obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a newly allocated mutable vector whose elements contain the given arguments. It is analogous to `list`.

```scheme
(vector ’a ’b ’c)  ⇒  #(a b c)
```

**(immutable-vector&#x20;*****obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a newly allocated immutable vector whose elements contain the given arguments in the given order.

**(list->vector&#x20;*****list*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

**(list->immutable-vector&#x20;*****list*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

**(string->vector&#x20;*****str*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(string->vector&#x20;*****str start*****)**\
\&#xNAN;**(string->vector&#x20;*****str start end*****)**

The `string->vector` procedure returns a newly created mutable vector initialized to the elements of the string *str* between *start* and *end* (i.e. including all characters from index *start* to index *end*-1).

```scheme
(string->vector "ABC")  ⇒  #(#\A #\B #\C)
```

**(vector-copy&#x20;*****vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-copy&#x20;*****vector mutable*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start end*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start end mutable*****)**

Returns a newly allocated copy of the elements of the given 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.

*mutable* is a boolean argument. If it is set to `#f`, an immutable copy of *vector* will be created. The type of the second argument of `vector-copy` is used to disambiguate between the second and third version of the function. An exact integer will always be interpreted as *start*, a boolean value will always be interpreted as *mutable*.

```scheme
(define a #(1 8 2 8))         ; a may be immutable
(define b (vector-copy a))    ; creates a mutable copy of a
(vector-set! b 0 3)           ; b is mutable
b  ⇒  #(3 8 2 8)
(define c (vector-copy a #f)) ; creates an immutable copy of a
(vector-set! c 0 3)  ⇒  error  ; error, since c is immutable
(define d (vector-copy b 1 3))
d  ⇒  #(8 2)
```

**(vector-append&#x20;*****vector ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

**(vector-concatenate&#x20;*****vector xs*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

**(vector-map&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Constructs a new mutable 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
(vector-map + #(1 2 3 4 5) #(10 20 30 40))  ⇒  #(11 22 33 44)
```

**(vector-map/index&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Constructs a new mutable 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
(vector-map/index (lambda (i x y) (cons i (+ x y))) #(1 2 3) #(10 20 30))
⇒  #((0 . 11) (1 . 22) (2 . 33))
```

**(vector-sort&#x20;*****pred vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-sort&#x20;*****pred vector start*****)**\
\&#xNAN;**(vector-sort&#x20;*****pred vector start end*****)**

Procedure `vector-sort` returns a new vector containing the elements of *vector* in sorted order using *pred* as the "less than" predicate. If *start* and *end* are given, they indicate the sub-vector that should be sorted.

```scheme
(vector-sort < (vector 7 4 9 1 2 8 5))
⇒  #(1 2 4 5 7 8 9)
```

## Iterating over vectors

**(vector-for-each&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

`vector-for-each` implements a simple vector iterator: it applies *f* to 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. In contrast with `vector-map`, *f* is reliably applied to each subsequent element, starting at index 0, in the vectors.

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

**(vector-for-each/index&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

`vector-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 `vector-for-each` is that `vector-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
(vector-for-each/index
  (lambda (i x) (display i)(display ": ")(display x)(newline))
  #("foo" "bar" "baz" "quux" "zot"))
⇒
0: foo
1: bar
2: baz
3: quux
4: zot
```

## Managing vector state

**(vector-length&#x20;*****vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

**(vector-ref&#x20;*****vector k*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

**(vector-set!&#x20;*****vector k obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

```scheme
(let ((vec (vector 0 '(2 2 2 2) "Anna")))
  (vector-set! vec 1 '("Sue" "Sue"))
  vec)
  ⇒  #(0 ("Sue" "Sue") "Anna")
(vector-set! '#(0 1 2) 1 "doe")
  ⇒  error    ;; constant/immutable vector
```

**(vector-swap!&#x20;*****vector j k*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

The `vector-swap!` procedure swaps the element *j* of *vector* with the element *k* of *vector*.

## Destructive vector operations

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

**(vector-copy!&#x20;*****to at from*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-copy!&#x20;*****to at from start*****)**\
\&#xNAN;**(vector-copy!&#x20;*****to at from start end*****)**

Copies the elements of vector *from* between *start* and *end* to 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 `(- (vector-length to) at)` is less than `(- end start)`.

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

**(vector-fill!&#x20;*****vector fill*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-fill!&#x20;*****vector fill start*****)**\
\&#xNAN;**(vector-fill!&#x20;*****vector fill start end*****)**

The `vector-fill!` procedure stores *fill* in the elements of *vector* between *start* and *end*. *start* defaults to 0 and *end* defaults to the length of *vector*.

```scheme
(define a (vector 1 2 3 4 5))
(vector-fill! a ’smash 2 4)
a  ⇒  #(1 2 smash smash 5)
```

**(vector-reverse!&#x20;*****vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-reverse!&#x20;*****vector start*****)**\
\&#xNAN;**(vector-reverse!&#x20;*****vector start end*****)**

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

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

**(vector-sort!&#x20;*****pred vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector-sort!&#x20;*****pred vector start*****)**\
\&#xNAN;**(vector-sort!&#x20;*****pred vector start end*****)**

Procedure `vector-sort!` destructively sorts the elements of *vector* using the "less than" predicate *pred* between the indices *start* and *end*. Default for *start* is 0, for *end* it is the length of the vector.

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

**(vector-map!&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

**(vector-map/index!&#x20;*****f vector1 vector2 ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

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

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

## Converting vectors

**(vector->list&#x20;*****vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector->list&#x20;*****vector start*****)**\
\&#xNAN;**(vector->list&#x20;*****vector start end*****)**

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

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

**(vector->string&#x20;*****vector*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(vector->string&#x20;*****vector start*****)**\
\&#xNAN;**(vector->string&#x20;*****vector start end*****)**

The `vector->string` procedure returns a newly allocated string of the objects contained in the elements of *vector* between *start* and *end*. This procedure preserves the order of the characters. It is an error if any element of vector between *start* and *end* is not a character.

```scheme
(vector->string #(#\1 #\2 #\3)  ⇒  "123"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.lisppad.app/libraries/lispkit/lispkit-vector.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
