Laboratory Exercises For Computer Science 151

Vectors

Vectors

Goals: This laboratory exercise reviews basic elements of vectors within Scheme.

Section 9.1 of Springer and Friedman's textbook describes the basic rationale for vectors in Scheme.

  1. Reread Section 9.1 of Springer and Friedman's textbook.

  2. Write a few sentences (at least 3) describing the motivation and overall idea behind Scheme's vector type.
Section 9.2 of Springer and Friedman's textbook introduces a vector as a collection of elements which are indexed by integers from 0 through n-1, where n is the length of the vector.

Representation of Vectors: Just as a vector is a sequence of characters enclosed in double quotes ("), a vector is a sequence of elements beginning with #( and ending with ). Thus, the following are valid vectors with four components:


#(2 3/4 -7 3.14179)
#(3 #\a "fred" henry)
Chez Scheme also allows a notation where the number of components in a vector is placed between the opening number sign # and the left parenthesis (, as shown below:

#4(2 3/4 -7 3.14179)
#4(3 #\a "fred" henry)
The vector? predicate tests whether or not an element is a vector. Some examples are:

(vector? #(2 3/4 -7 3.14179)) ==> #t
(vector? #4(3 #\a "fred" henry)) ==> #t
(vector? "fred") ==> #f
Constructing Vectors: In addition to explicitly writing out a vector (e.g., the vector literals above), vectors can be constructed with either of two constructor procedures, vector and make-vector.

vector makes a vector out of the elements that follow, as shown in these examples:


(vector 2 3/4 -7 3.14179)
(vector 3 #\a "fred" 'henry)
make-vector constructs a vector of a specified length. If a second argument is given, then each component of the new vector contains a copy of the value of the second argument. For example, (make-vector 5) produces a vector with five components, and (make-vector 5 7) generates a vector of 5 elements, each of which contains the number 7. Thus, (make-vector 5 7) produces the vector #5(7 7 7 7 7) .

Accessor Procedures: Once a vector is produced, the vector-length procedure returns its length (its number of components), and vector-ref returns the element in a given position. Some examples follow.


(vector-length #(3 #\a "fred" henry)) ==> 4
(vector-length #()) ==> 0
(vector-ref #(3 #\a "fred" henry) 0) ==> 3
(vector-ref #(3 #\a "fred" henry) 2) ==> "fred"
(vector-ref #(3 #\a "fred" henry) 6) ==> error:  invalid index
Remember that components of a vector are indexed, beginning with index 0. Thus, 3 is element 0 in the vector #(3 #\a "fred" henry)

Conversion Procedures The procedures vector->list and list->vector allow us to convert vectors to lists and conversely. Some examples are:


(vector->list #(3 #\a "fred" henry)) ==> (3 #\a "fred" henry)
(list->vector '(3 #\a "fred" henry)) ==> #4(3 #\a "fred" henry)
These operations are summarized in the following table:

Procedure Sample Call Result of Example Comment
vector?(vector? #('a 'b 'c)) #t Return true (#t) if element is a vector
vector(vector 'a 'b 'c) #('a 'b 'c) Make a vector of the parameters
make-vector(make-vector 4) #(__ __ __ __) Make an uninitialized vector of the given length
make-vector(make-vector 4 5) #(5 5 5 5) Make vector with length, with all components specified
vector-length(vector-length #('a 'b 'c)) 3 Return length of given vector
vector-ref(vector-ref #('a 'b 'c) 1) 'b Return given component of vector
vector->list(vector->list #('a 'b 'c)) ('a 'b 'c) Converts vector to corresponding list
list->vector(list->vector '(a b c)) #3(a b c) Converts list to corresponding vector
Section 9.2 of Springer and Friedman's text defines a procedure view as follows:


(define view
   (lambda (vec)
      (let ((highest-index (sub1 (vector-length vec))))
          (letrec ((loop (lambda (i)
                             (display (vector-ref vec i))
                             (if (< i highest-index)
                                 (begin
                                     (display " ")
                                     (loop (add1 i)))))))
              (display "#(")
              (loop 0)
              (display ")")))))

  1. Run view on several vector examples (such as those appearing earlier in this lab) to check what this procedure does.

  2. Write a paragraph explaining how view works.

  3. As already noted, Chez Scheme prints a number after the initial # symbol in a symbol, indicating how many elements are present in a vector. Modify view, so that it also prints this length.

  4. Define a Scheme procedure named vector-of that does for vectors what the list-of procedure (from the lab on procedure abstraction) does for lists: Given any predicate, pred?, vector-of should return a predicate that takes a vector as argument and determines whether each of its elements satisfies pred?.
    ((vector-of even?) '#(6 2 4 10 -18)) ===> #t
    ((vector-of positive?) '#(6 2 4 10 -18)) ===> #f
    ((vector-of symbol?) '#(a b)) ===> #t
    ((vector-of real?) '#()) ===> #t
    

This document is available on the World Wide Web as

http://www.math.grin.edu/~walker/courses/151/lab-vectors.html

created April 3, 1997
last revised April 13, 1997