Vectors

Vectors are heterogeneous structures whose elements are indexed by integers. A vector typically occupies less space than a list of the same length, and the average time needed to access a randomly chosen element is typically less for the vector than for the list.

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 indices of a vector are the exact non–negative integer objects 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.

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

#(0 (2 2 2 2) "Anna")

Note that this is the external representation of a vector. In Kawa, a vector datum is self-evaluating, but for style (and compatibility with R7RS) is is suggested you quote a vector constant:

’#(0 (2 2 2 2) "Anna")  ⇒ #(0 (2 2 2 2) "Anna")

Compare these different ways of creating a vector:

(vector a b c)

In this case a, b, and c are expressions evaluated at run-time and the results used to initialize a newly-allocated 3-element vector.

[a b c]

Same as using vector, but more concise, and results in an immutable (non-modifiable) vector.

#(a b c)

This is reader syntax and creates a vector literal, at read-time, early in compile-time. The symbols a, b, and c are not evaluated but instead used literally.

`#(,a ,b ,c)

This is reader-syntax, using quasi-quotation, so a, b, and c are expressions evaluated at run-time. This is equivalent to [a b c] in that it results in an immutable vector.

Type: vector

The type of vector objects.

Constructor: vector obj

Return a newly allocated vector whose elements contain the given arguments. Analogous to list.

(vector 'a 'b 'c)               ⇒  #(a b c)

Alternatively, you can use square-bracket syntax, which results in an immutable vector:

['a 'b 'c]               ⇒  #(a b c)

Procedure: make-vector k

Procedure: make-vector k fill

Return 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 #!null.

Procedure: vector? obj

Return #t if obj is a vector, #f otherwise.

Procedure: vector-length vector

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

Procedure: vector-ref vector k

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

(vector-ref '#(1 1 2 3 5 8 13 21) 5)     ⇒  8
(vector-ref '#(1 1 2 3 5 8 13 21)
  (inexact->exact (round (* 2 (acos -1)))))
⇒ 13

Procedure: vector-set! vector k obj

It is an error if k is not a valid index of vector. The vector-set! procedure stores obj in element k of vector, and returns no values.

(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 vector

A concise alternative to vector-ref and vector-set! is to use function call syntax. For example:

(let ((vec (vector 0 '(2 2 2 2) "Anna")))
  (set! (vec 1) '("Sue" "Sue"))
  (list (vec 2) (vec 1)))
  ⇒  ("Anna" ("Sue" "Sue"))

Procedure: vector->list 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.

(vector->list '#(dah dah didah))        ⇒  (dah dah didah)
(vector->list '#(dah dah didah) 1 2)    ⇒  (dah)

Procedure: list->vector list

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

(list->vector '(dididit dah))           ⇒  #(dididit dah)

Procedure: vector->string 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. It is an error if any element of vector between start and end is not a character, or is a character forbidden in strings.

(vector->string #(#\1 #\2 #\3))             ⇒ "123"
(vector->string #(#\1 #\2 #\3 #\4 #\5) 2 4) ⇒ "34"

Procedure: string->vector string [start [end]]

The string->vector procedure returns a newly created vector initialized to the elements of the string string between start and end.

(string->vector "ABC")       ⇒ #(#\A #\B #\C)
(string->vector "ABCDE" 1 3) ⇒ #(#\B #\C)

Procedure: vector-copy vector [start [end]]

Returns a newly allocated copy of the elements of the given vector between start and end . The elements of the new vector are the same (in the sense of eqv?) as the elements of the old.

(define a #(1 8 2 8)) ; a may be immutable
(define b (vector-copy a))
(vector-set! b 0 3)   ; b is mutable
b                     ⇒      #(3 8 2 8)
(define c (vector-copy b 1 3))
c                     ⇒ #(8 2)

Procedure: vector-copy! 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. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.

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).

(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)

Procedure: vector-append arg...

Creates a newly allocated vector whose elements are the concatenation of the elements of the given arguments. Each arg may be a vector or a list.

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

Procedure: vector-fill! vector fill [start [end]]

Stores fill in in the elements of vector between start and end.

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

Procedure: vector-map proc vector_1 vector_2

The vectors must all have the same length. proc should accept as many arguments as there are vectors and return a single value.

The vector-map procedure applies proc element–wise to the elements of the vectors and returns a vector of the results, in order. proc is always called in the same dynamic environment as vector-map itself. The order in which proc is applied to the elements of the vectors is unspecified. If multiple returns occur from vector-map, the return values returned by earlier returns are not mutated.

Analogous to map.

Procedure: vector-for-each proc vector_1 vector_2

The vectors must all have the same length. proc should accept as many arguments as there are vectors. The vector-for-each procedure applies proc element–wise to the elements of the vectors for its side effects, in order from the first elements to the last. proc is always called in the same dynamic environment as vector-for-each itself. The return values of vector-for-each are unspecified.

Analogous to for-each.