Vectors

Overview

A vector is a fixed-length, indexed collection of elements. Unlike a list, which is composed of linked pairs and optimized for sequential access, a vector stores its elements in contiguous memory and allows direct access by numeric index. Vectors are written using the literal syntax #( … ).

#(1 2 3 4)
#("a" "b" "c")

You can think of a vector as an array. Each element is stored at a specific position, starting from index 0. Accessing an element by index is efficient and does not require traversing the structure from the beginning, as lists do. For example:

--> (define v #(10 20 30))
v
--> (vector-ref v 1)
20

Vectors are implemented internally using C-level arrays. This means their elements are stored contiguously in memory, allowing constant-time indexed access. If your program frequently accesses elements by position, modifies elements in place, or needs predictable performance for indexed operations, vectors are generally more efficient than lists.

Lists, by contrast, are better suited for recursive processing, structural decomposition (using car and cdr), and situations where the collection size changes frequently. Lists grow and shrink naturally, while vectors have a fixed size once created. Although a new vector can be created with a different size, its length cannot be changed after allocation.

Vectors are especially useful for:

  • Storing data where position matters

  • Numerical computations

  • Implementing tables or buffers

  • Situations requiring frequent indexed access

  • Performance-sensitive code

Like lists, vectors can store any first-class object, including numbers, strings, procedures, and even other vectors. However, unlike lists, they are not constructed from pairs and cannot be processed using car and cdr.

Because vectors are mutable, procedures ending in ! may modify their contents in place:

--> (define v #(1 2 3))
v
--> (vector-set! v 0 42)
--> v
#(42 2 3)

Vectors combine the flexibility of heterogeneous storage with the performance characteristics of arrays, making them an important general-purpose data structure.

Vector Procedures

vector

(vector obj ...)

Returns a newly allocated vector whose elements are the given arguments, in order. If no arguments are provided, returns an empty vector. Analogous to list.

Parameters:

obj (any) – Zero or more objects to store in the vector.

Returns:

A new vector containing obj

Return type:

vector

Example:

--> (vector 1 2 3)
#(1 2 3)
--> (vector 'a "hello" #t)
#(a "hello" #t)
--> (vector)
#()

vector-length

(vector-length vector)

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

Parameters:

vector (vector) – The vector to measure.

Returns:

The number of elements in vector.

Return type:

integer

Example:

--> (vector-length #(1 2 3))
3
--> (vector-length #())
0

vector-ref

(vector-ref vector k)

Returns the element at index k in vector, where the first element is at index 0. Raises an error if k is negative or out of range.

Parameters:
  • vector (vector) – The vector to index into.

  • k (integer) – The zero-based index of the element to retrieve.

Returns:

The element at index k.

Return type:

any

Example:

--> (vector-ref #(a b c d) 0)
a
--> (vector-ref #(a b c d) 2)
c

make-vector

(make-vector k [fill])

Returns a newly allocated vector of k elements. If fill is provided, every element is initialised to fill. Otherwise, every element is initialised to 0. k must be a non-negative integer.

Parameters:
  • k (integer) – The number of elements in the new vector.

  • fill (any) – The value to fill each element with. Defaults to 0.

Returns:

A new vector of k elements.

Return type:

vector

Example:

--> (make-vector 3)
#(0 0 0)
--> (make-vector 4 'x)
#(x x x x)
--> (make-vector 0)
#()

list->vector

(list->vector list)

Returns a newly allocated vector containing the elements of list, in order. If list is empty, an empty vector is returned.

Parameters:

list (list) – A proper list of elements to store in the vector.

Returns:

A new vector containing the elements of list.

Return type:

vector

Example:

--> (list->vector '(a b c))
#(a b c)
--> (list->vector '())
#()
--> (list->vector '(1 (2 3) 4))
#(1 (2 3) 4)

vector->list

(vector->list vector [start [end]])

Returns a newly allocated list of the elements of vector between start (inclusive) and end (exclusive). start defaults to 0 and end defaults to the length of vector. Order is preserved.

Parameters:
  • vector (vector) – The vector to convert.

  • start (integer) – The index of the first element to include. Defaults to 0.

  • end (integer) – The index past the last element to include. Defaults to the length of vector.

Returns:

A new list of the elements of vector between start and end.

Return type:

list

Example:

--> (vector->list #(a b c d))
(a b c d)
--> (vector->list #(a b c d) 1)
(b c d)
--> (vector->list #(a b c d) 1 3)
(b c)
--> (vector->list #())
()

vector-copy

(vector-copy vector [start [end]])

Returns a newly allocated copy of the elements of vector between start (inclusive) and end (exclusive). start defaults to 0 and end defaults to the length of vector. The elements of the new vector are the same (in the sense of eqv?) as the elements of the original.

Parameters:
  • vector (vector) – The vector to copy.

  • start (integer) – The index of the first element to include. Defaults to 0.

  • end (integer) – The index past the last element to include. Defaults to the length of vector.

Returns:

A new vector containing the specified elements of vector.

Return type:

vector

Example:

--> (vector-copy #(a b c d))
#(a b c d)
--> (vector-copy #(a b c d) 1)
#(b c d)
--> (vector-copy #(a b c d) 1 3)
#(b c)

vector->string

(vector->string vector [start [end]])

Returns a newly allocated string formed from the characters stored in vector between start (inclusive) and end (exclusive). Every element of vector in the specified range must be a character. start defaults to 0 and end defaults to the length of vector. Order is preserved.

Parameters:
  • vector (vector) – A vector of characters.

  • start (integer) – The index of the first element to include. Defaults to 0.

  • end (integer) – The index past the last element to include. Defaults to the length of vector.

Returns:

A new string composed of the characters in vector between start and end.

Return type:

string

Example:

--> (vector->string #(#\h #\e #\l #\l #\o))
"hello"
--> (vector->string #(#\h #\e #\l #\l #\o) 1)
"ello"
--> (vector->string #(#\h #\e #\l #\l #\o) 1 3)
"el"

string->vector

(string->vector string [start [end]])

Returns a newly allocated vector of the characters of string between start (inclusive) and end (exclusive). start defaults to 0 and end defaults to the length of string. Order is preserved. Character indices are by Unicode code point, not by byte offset.

Parameters:
  • string (string) – The string to convert.

  • start (integer) – The index of the first character to include. Defaults to 0.

  • end (integer) – The index past the last character to include. Defaults to the length of string.

Returns:

A new vector of the characters of string between start and end.

Return type:

vector

Example:

--> (string->vector "hello")
#(#\h #\e #\l #\l #\o)
--> (string->vector "hello" 1)
#(#\e #\l #\l #\o)
--> (string->vector "hello" 1 3)
#(#\e #\l)

vector-set!

(vector-set! vector k obj)

Stores obj at index k of vector, mutating it in place. Raises an error if k is negative or out of range. Returns an unspecified value.

Parameters:
  • vector (vector) – The vector to mutate.

  • k (integer) – The zero-based index at which to store obj.

  • obj (any) – The value to store.

Returns:

Unspecified.

Example:

--> (define v (vector 'a 'b 'c))
--> (vector-set! v 1 'z)
--> v
#(a z c)

vector-append

(vector-append vector ...)

Returns a newly allocated vector whose elements are the concatenation of the elements of all vector arguments, in order. If no arguments are provided, returns an empty vector. If exactly one argument is provided, it is returned unchanged.

Parameters:

vector (vector) – Zero or more vectors to concatenate.

Returns:

A new vector containing all elements of all vector arguments.

Return type:

vector

Example:

--> (vector-append #(1 2) #(3 4))
#(1 2 3 4)
--> (vector-append #(a b) #(c d) #(e f))
#(a b c d e f)
--> (vector-append #())
#()
--> (vector-append)
#()

vector-copy!

(vector-copy! to at from [start [end]])

Copies the elements of vector from between start (inclusive) and end (exclusive) into vector to, starting at index at, mutating to in place. start defaults to 0 and end defaults to the length of from. If the source and destination ranges overlap, the copy is performed correctly as if via a temporary intermediate vector. Returns an unspecified value.

Raises an error if any index argument is out of range, or if the target range in to would exceed its length.

Parameters:
  • to (vector) – The destination vector to copy elements into.

  • at (integer) – The index in to at which to begin writing.

  • from (vector) – The source vector to copy elements from.

  • start (integer) – The index of the first element in from to copy. Defaults to 0.

  • end (integer) – The index past the last element in from to copy. Defaults to the length of from.

Returns:

Unspecified.

Example:

--> (define v (vector 'a 'b 'c 'd 'e))
--> (vector-copy! v 1 #(x y z))
--> v
#(a x y z e)
--> (vector-copy! v 0 #(x y z) 1 3)
--> v
#(y z y z e)

vector-fill!

(vector-fill! vector fill [start [end]])

Stores fill in every element of vector between start (inclusive) and end (exclusive), mutating vector in place. start defaults to 0 and end defaults to the length of vector. If start and end are equal, the procedure has no effect. Returns an unspecified value.

Parameters:
  • vector (vector) – The vector to fill.

  • fill (any) – The value to store in each element.

  • start (integer) – The index of the first element to fill. Defaults to 0.

  • end (integer) – The index past the last element to fill. Defaults to the length of vector.

Returns:

Unspecified.

Example:

--> (define v (vector 'a 'b 'c 'd 'e))
--> (vector-fill! v 'z)
--> v
#(z z z z z)
--> (vector-fill! v 'x 1 3)
--> v
#(z x x z z)
--> (vector-fill! v 'y 2)
--> v
#(z x y y y)

vector-map

(vector-map proc vector ...)

Applies proc element-wise to the elements of each vector argument and returns a new vector of the results, in order. proc must accept as many arguments as there are vectors. If more than one vector is given and they differ in length, iteration stops when the shortest vector is exhausted.

Parameters:
  • proc (procedure) – A procedure accepting as many arguments as there are vectors.

  • vector (vector) – One or more vectors to map over.

Returns:

A new vector of the results of applying proc to each set of elements.

Return type:

vector

Example:

--> (vector-map (lambda (x) (* x x)) #(1 2 3 4 5))
#(1 4 9 16 25)
--> (vector-map + #(1 2 3) #(10 20 30))
#(11 22 33)
--> (vector-map + #(1 2 3) #(10 20))
#(11 22)
--> (vector-map car #(()))
#()

vector-for-each

(vector-for-each proc vector ...)

Applies proc element-wise to the elements of each vector argument, in order, for its side effects. Unlike vector-map, the results of proc are discarded. proc must accept as many arguments as there are vectors. If more than one vector is given and they differ in length, iteration stops when the shortest vector is exhausted. Returns an unspecified value.

Parameters:
  • proc (procedure) – A procedure accepting as many arguments as there are vectors.

  • vector (vector) – One or more vectors to iterate over.

Returns:

Unspecified.

Example:

--> (vector-for-each display #(1 2 3))
123
--> (define result '())
--> (vector-for-each
...   (lambda (x) (set! result (cons (* x x) result)))
...   #(1 2 3))
--> result
(9 4 1)