CSC 153  Grinnell College  Spring, 2005 
Computer Science Fundamentals  
Laboratory Exercise  
This laboratory exercise reviews basic elements of vectors within Scheme.
A vector is a collection of elements which are indexed by integers from 0 through n1, where n is the length of the vector. Furthermore, in Scheme, vectors have the property that any element within a vector may be accessed directly. As an example, consider a list of 10 names and a vector of the same names:
In order to find the seventh name (MacKay) in the list, we must start at the first element and move elementbyelement to get the desired item. Within the vector, however, we simply specify the appropriate index (since indexing starts at 0, the seventh item is in position 6).
Just as a string 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
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 makevector.
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)
makevector 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, (makevector 5) produces a vector with five components, and (makevector 5 7) generates a vector of 5 elements, each of which contains the number 7. Thus, (makevector 5 7) produces the vector #5(7 7 7 7 7) .
Once a vector is produced, the vectorlength procedure returns its length (its number of components), and vectorref returns the element in a given position. Some examples follow.
(vectorlength #(3 #\a "fred" henry)) ==> 4 (vectorlength #()) ==> 0 (vectorref #(3 #\a "fred" henry) 0) ==> 3 (vectorref #(3 #\a "fred" henry) 2) ==> "fred" (vectorref #(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)
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 
makevector  (makevector 4)  #(__ __ __ __)  Make an uninitialized vector of the given length 
makevector  (makevector 4 5)  #(5 5 5 5)  Make vector with length, with all components specified 
vectorlength  (vectorlength #('a 'b 'c))  3  Return length of given vector 
vectorref  (vectorref #('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 
Now consider the procedure view as follows:
(define view (lambda (vec) ;Precondition: vec is a vector ;Postcondition: vec is printed at the keyboard (let ((highestindex (sub1 (vectorlength vec)))) (display "#(") (let loop ((i 0)) (display (vectorref vec i)) (if (< i highestindex) (begin (display " ") (loop (add1 i)))))) (display ")")))
Write a procedure vectorfind that searches a vector for a given item. If the item is found, vectorfind should return the location of the first occurrence of the item. If the vector is not present, vectorfind should return 1.
(vectorfind 4 '#(6 2 4 10 18)) ===> 2 (vectorfind 5 '#(6 2 4 10 18)) ===> 1 (vectorfind 'a '#(a b)) ===> 0 (vectorfind 'a '#()) ===> 1
Define a higherorder Scheme procedure named vectorof
that
returns a procedure for checking that all elements of a vector satisfy a
specified predicate. That is, given any predicate, pred?
,
vectorof
should return a predicate that takes a vector as
argument and determines whether each of its elements satisfies
pred?
.
((vectorof even?) '#(6 2 4 10 18)) ===> #t ((vectorof positive?) '#(6 2 4 10 18)) ===> #f ((vectorof symbol?) '#(a b)) ===> #t ((vectorof real?) '#()) ===> #t
In the reading on sorting and mutation, Scheme's procedure set! was introduced as a means to change the value of a variable. Similarly, procedure vectorset! changes the value stored in a designated location within a vector. The form for vectorset! is:
(vectorset! vect index newvalue)
That is, within vector vect, the element at the given index is changed to the specified newvalue.
As the following examples indicate, procedure vectorset! itself does not return a new value  rather it changes parameter vect.
(define x #(3 #\a "fred" 0.31894 12/5)) x (vectorset! x 3 "susan") x (vectorset! x 1 3.141592) x (define f (lambda (y) (vectorset! y 4 15))) (f x) x (vectorset! #(1 2 3 4 5 6) 3 10) (define y #(1 2 3 4 5 6)) (vectorset! y 3 10) y
Again, it is important to emphasize that vectorset! need not return a useful value. (Standard Scheme does not specify what is value returned.) Instead, the vector parameter to vectorset! changes. Further, this change even occurs when vectorset! is applied within another function  x changes in the call (f x), since f in turn calls vectorset!.
Similarly, procedure vectorfill! changes all components of a given vector to a specified value, as illustrated in the following sequence:
(define x #(3 #\a "fred" 0.31894 12/5)) x (vectorfill! x "henry") x (vectorset! x 3 "terry") x
In this example, note that Chez Scheme uses a shorthand notation when printing a vector, all of whose components are identical. In particular, Chez Scheme prints
#5("henry")
to represent a vector of five components, with each component being the string "henry".
If this notation #5("henry") seems confusing, Chez Scheme can provide a more conventional output of vectors. First, type
(printvectorlength #f)
In subsequent lines, vectors will be printed showing each component.
After using the printvectorlength procedure as shown, try the above sequence (with vectorfill!) to see this alternative output.
To restore the previous format for printing vectors, type
(printvectorlength #t)
In writing Scheme procedures, it is common to use an exclamation point (!) at the end of a procedure name, when that procedure changes a parameter.
vectoriota
that takes a
natural number n
as argument and returns a vector of length
n
containing all of the natural numbers less than
n
, in ascending order.
(vectoriota 9) ===> #9(0 1 2 3 4 5 6 7 8) (vectoriota 2) ===> #2(0 1) (vectoriota 0) ===> #0()
This document is available on the World Wide Web as
http://www.cs.grinnell.edu/~walker/courses/153.sp05/labs/labvectors.shtml
created April 3, 1997 last revised February 3, 2005 

For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. 