LispPad

Lightweight Scheme Development Tool for macOS

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? obj)     [procedure]

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

(mutable-vector? obj)     [procedure]

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

(immutable-vector? obj)     [procedure]

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

(vector= eql vector ...)     [procedure]

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.


(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 k)     [procedure]
(make-vector 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 obj ...)     [procedure]

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


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

(immutable-vector obj ...)     [procedure]

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

(list->vector list)

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


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

(list->immutable-vector list)

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 str)
(string->vector str start)
(string->vector 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).


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

(vector-copy vector)     [procedure]
(vector-copy vector mutable)
(vector-copy vector start)
(vector-copy vector start end)
(vector-copy 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.


(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 vector ...)     [procedure]

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


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

(vector-concatenate vector xs)     [procedure]

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.


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

(vector-map f vector1 vector2 ...)     [procedure]

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.


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

(vector-map/index f vector1 vector2 ...)     [procedure]

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.


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

Managing vector state

(vector-length vector)     [procedure]

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

(vector-ref vector k)     [procedure]

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.


(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! vector k obj)     [procedure]

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


(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! vector j k)     [procedure]

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! to at from)     [procedure]
(vector-copy! to at from start)
(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. 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).


(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! vector fill)     [procedure]
(vector-fill! vector fill start)
(vector-fill! 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.


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

(vector-reverse! vector)     [procedure]
(vector-reverse! vector start)
(vector-reverse! 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.


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

(vector-sort! pred vector)     [procedure]

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


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

(vector-map! f vector1 vector2 ...)     [procedure]

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.


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

(vector-map/index! f vector1 vector2 ...)     [procedure]

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.


(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 vector)     [procedure]
(vector->list vector start)
(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 in the same order line in vector.


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

(vector->string vector)     [procedure]
(vector->string vector start)
(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. 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.


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