Revised7 Report on the Algorithmic Language Scheme
Batteries

1: R7RS Vector library

The (scheme vector) library provides constructors, predicates, iteration, searching, mutation, and conversion procedures for vectors.

1.1: Argument conventions

The arguments vector, to, and from must be vectors. The argument list must be a list. The arguments k, length, at, start, and end must be exact non-negative integers.

A range begins at start (inclusive) and ends at end (exclusive). These arguments must satisfy (<= 0 start end (vector-length vector)) for the vector whose elements are selected. When omitted, start defaults to zero and end defaults to the length of that vector. In copying procedures, the range refers to from.

The argument f must be a procedure returning one value, except where multiple return values are specified. The argument pred? must be a procedure returning one value, which is treated as a boolean. When parallel elements of several vectors are passed to a procedure, they are passed in the order of the vector arguments.

The arguments obj, initial-seed, knil, and value may be arbitrary Scheme objects.

1.2: Constructors

1.2.1: vector-unfold

  • (vector-unfold f length initial-seed …) procedure
Restrictions

It is an error for the number of seeds to vary between iterations.

Description

The fundamental vector constructor. Creates a vector whose length is length and iterates across each index k from zero (inclusive) to length (exclusive), applying f at each iteration to the current index and current seeds, in that order. The first value returned is the element to put in the kth slot of the new vector; the remaining values are the new seeds for the next iteration, one for each initial seed.

Note: The termination condition differs from that of unfold.

Examples
(vector-unfold (lambda (k obj) (values obj (- obj 1)))
               10 0)⇒ #(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)

Construct a vector of consecutive non-negative integers.

(vector-unfold values 5)⇒ #(0 1 2 3 4)

Copy vector.

(vector-unfold (lambda (k) (vector-ref vector k))
               (vector-length vector))

1.2.2: vector-unfold-right

  • (vector-unfold-right f length initial-seed …) procedure
Description

Like vector-unfold, but uses f to generate elements from right to left rather than left to right. The first index used is (- length 1).

Note: The termination condition differs from that of unfold-right.

Examples

Construct a vector of pairs of non-negative integers whose values sum to 4.

(vector-unfold-right
  (lambda (k obj) (values (cons k obj) (+ obj 1)))
  5 0)⇒ #((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0))

Reverse vector.

(vector-unfold-right
  (lambda (k obj)
    (values (vector-ref vector obj) (+ obj 1)))
  (vector-length vector)
  0)

1.2.3: vector-reverse-copy

  • (vector-reverse-copy vector [start [end]]) procedure
Description

Like vector-copy, but copies the elements of vector in reverse order.

Examples
(vector-reverse-copy '#(5 4 3 2 1 0) 1 5)⇒ #(1 2 3 4)

1.2.4: vector-concatenate

  • (vector-concatenate list-of-vectors) procedure
Restrictions

list-of-vectors must be a list of vectors.

Description

Appends each vector in list-of-vectors. This is equivalent to:

(apply vector-append list-of-vectors)

However, it may be implemented more efficiently than this call to apply and vector-append.

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

1.2.5: vector-append-subvectors

  • (vector-append-subvectors (vector start end) …) procedure
Description

Returns a vector that contains every element of each vector from start (inclusive) to end (exclusive), in the specified order. This procedure is a generalization of vector-append.

Examples
(vector-append-subvectors '#(a b c d e) 0 2
                          '#(f g h i j) 2 4)⇒ #(a b h i)

1.3: Predicates

1.3.1: vector-empty?

  • (vector-empty? vector) procedure
Description

Returns #t if vector is empty, i.e. its length is zero, and #f otherwise.

Examples
(vector-empty? '#(a))⇒ #f
(vector-empty? '#(()))⇒ #f
(vector-empty? '#(#()))⇒ #f
(vector-empty? '#())⇒ #t

1.3.2: vector=

  • (vector= elt=? vector …) procedure
Restrictions

elt=? must be a procedure accepting two arguments and returning one value, which is treated as a boolean.

Description

Vector structure comparator, generalized across user-specified element comparators. Two vectors are considered equal by vector= if and only if their lengths are the same and elt=? returns a true value for each pair of corresponding elements. elt=? is always applied to two arguments.

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

Examples
(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 2 3 4))⇒ #t

The two trivial cases:

(vector= eq?)⇒ #t
(vector= eq? '#(a))⇒ #t

The following examples allocate vectors because it is unspecified whether literal vectors with the same external representation are eq?.

(vector= eq? (vector (vector 'a)) (vector (vector 'a)))⇒ #f
(vector= equal? (vector (vector 'a)) (vector (vector 'a)))⇒ #t

1.4: Iteration

1.4.1: vector-fold

  • (vector-fold kons knil vector1 vector2 …) procedure
Restrictions

kons must accept one more argument than there are vectors and return one value.

Description

The fundamental vector iterator. kons is iterated over each value in all of the vectors, stopping at the end of the shortest. It is applied as:

(kons state (vector-ref vector1 k) (vector-ref vector2 k) ...)

Here state is the current state value, which begins with knil and becomes whatever kons returned on the previous iteration, and k is the current index. The iteration is strictly left to right. The final state value is returned.

Examples

Find the longest string's length in vector-of-strings.

(vector-fold (lambda (len str)
               (max (string-length str) len))
             0 vector-of-strings)

Produce a list of the reversed elements of vector.

(vector-fold (lambda (tail elt) (cons elt tail))
             '() vector)

Count the number of even numbers in vector.

(vector-fold (lambda (counter n)
               (if (even? n) (+ counter 1) counter))
             0 vector)

1.4.2: vector-fold-right

  • (vector-fold-right kons knil vector1 vector2 …) procedure
Description

Similar to vector-fold, but iterates right to left instead of left to right.

Examples

Convert a vector to a list.

(vector-fold-right (lambda (tail elt) (cons elt tail))
                   '() vector)

1.4.3: vector-map!

  • (vector-map! f vector1 vector2 …) procedure
Restrictions

f must accept as many arguments as there are vectors and return one value. It is an error if vector1 contains more elements than any of the other vectors.

Description

Similar to vector-map, but the mapped elements are destructively inserted into vector1 rather than into a new vector. The dynamic order of application of f is unspecified.

Note: Because the order of application is unspecified, it is dangerous for f to apply vector-ref or vector-set! to vector1.

1.4.4: vector-count

  • (vector-count pred? vector1 vector2 …) procedure
Description

Counts the number of parallel elements in the vectors that satisfy pred?. For each index from zero (inclusive) to the length of the shortest vector (exclusive), pred? is applied to the corresponding elements of the vectors, in order.

Examples
(vector-count even? '#(3 1 4 1 5 9 2 5 6))⇒ 3
(vector-count < '#(1 3 6 9) '#(2 4 6 8 10 12))⇒ 2

1.4.5: vector-cumulate

  • (vector-cumulate f knil vector) procedure
Restrictions

f must accept two arguments and return one value.

Description

Returns a newly allocated vector with the same length as vector. Each element of the new vector is set to the result of invoking f on the preceding element of the new vector and the corresponding element of vector, except that for the first call to f, the first argument is knil.

Examples
(vector-cumulate + 0 '#(3 1 4 1 5 9 2 5 6))⇒ #(3 4 8 9 14 23 25 30 36)

1.5: Searching

1.5.1: vector-index

  • (vector-index pred? vector1 vector2 …) procedure
Description

Finds and returns the index of the first parallel elements in the vectors that satisfy pred?. If no matching elements are found by the end of the shortest vector, #f is returned.

Examples
(vector-index even? '#(3 1 4 1 5 9))⇒ 2
(vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))⇒ 1
(vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2))⇒ #f

1.5.2: vector-index-right

  • (vector-index-right pred? vector1 vector2 …) procedure
Restrictions

All of the vectors must have the same length.

Description

Like vector-index, but searches right to left rather than left to right.

1.5.3: vector-skip

  • (vector-skip pred? vector1 vector2 …) procedure
Description

Finds and returns the index of the first parallel elements in the vectors that do not satisfy pred?. If all the parallel elements satisfy pred? through the end of the shortest vector, returns #f. This is equivalent to:

(vector-index (lambda (obj1 obj2 ...)
                (not (pred? obj1 obj2 ...)))
              vector1 vector2 ...)
Examples
(vector-skip number? '#(1 2 a b 3 4 c d))⇒ 2

1.5.4: vector-skip-right

  • (vector-skip-right pred? vector1 vector2 …) procedure
Restrictions

It is an error if the vectors do not all have the same length.

Description

Like vector-skip, but searches for non-matching elements right to left rather than left to right. This is equivalent to:

(vector-index-right (lambda (obj1 obj2 ...)
                      (not (pred? obj1 obj2 ...)))
                    vector1 vector2 ...)

1.5.6: vector-any

  • (vector-any pred? vector1 vector2 …) procedure
Description

Finds the first set of parallel elements in the vectors for which pred? returns a true value. If such a set exists, vector-any returns the value that pred? returned for that set of elements. The iteration is strictly left to right.

The source does not explicitly specify termination at the shortest vector or the result when no elements match (including empty vectors). Confirm that the result is #f in these cases.

1.5.7: vector-every

  • (vector-every pred? vector1 vector2 …) procedure
Description

If, for every index from zero (inclusive) to the length of the shortest vector (exclusive), the set of corresponding elements satisfies pred?, vector-every returns the value that pred? returned for the last set of elements, at the last index of the shortest vector. The iteration is strictly left to right.

The source leaves the failure and empty-vector cases implicit. Confirm that iteration stops with #f at the first non-matching set and returns #t if any vector is empty.

1.5.8: vector-partition

  • (vector-partition pred? vector) procedure
Description

A vector the same size as vector is newly allocated and filled with all the elements of vector that satisfy pred? in their original order, followed by all the elements that do not satisfy pred?, also in their original order.

Two values are returned: the newly allocated vector and the number of elements that satisfy pred?.

1.6: Mutators

1.6.1: vector-swap!

  • (vector-swap! vector k1 k2) procedure
Restrictions

k1 and k2 must be valid indices of vector.

Description

Swaps the values of the locations in vector at k1 and k2.

1.6.2: vector-reverse!

  • (vector-reverse! vector [start [end]]) procedure
Description

Destructively reverses the contents of the sequence of locations in vector between start and end. start defaults to zero and end defaults to the length of vector.

Note: This does not deeply reverse.

1.6.3: vector-reverse-copy!

  • (vector-reverse-copy! to at from [start [end]]) procedure
Description

Like vector-copy!, but the elements appear in to in reverse order.

The source says only ‘Like vector-copy!’. Confirm that its temporary-vector semantics for overlapping source and destination also apply to the reverse copy.

1.6.4: vector-unfold!

  • (vector-unfold! f vector start end initial-seed …) procedure
Description

Like vector-unfold, but the elements are copied into vector starting at element start rather than into a newly allocated vector. Terminates when (- end start) elements have been generated.

1.6.5: vector-unfold-right!

  • (vector-unfold-right! f vector start end initial-seed …) procedure
Description

Like vector-unfold!, but the elements are copied in reverse order into vector starting at the index preceding end.

1.7: Conversion

1.7.1: reverse-vector->list

  • (reverse-vector->list vector [start [end]]) procedure
Description

Like vector->list, but the resulting list contains the elements of vector in reverse order.

1.7.2: reverse-list->vector

  • (reverse-list->vector list) procedure
Description

Like list->vector, but the resulting vector contains the elements of list in reverse order.

A.1: Bibliography