Laboratory Exercises For Computer Science 151

Structure Mutation

Structure Mutation

Goals: This laboratory exercise continues the work on vectors started in the previous lab by discussing the vector-set! and vector-fill! procedures. These procedures are examples of a general category of operations which change the structure of one of their parameters.

Modifying Vectors: The previous lab on vectors discussed the creating of vectors and the retrieval of data from vectors. We now consider how to modify an existing vector through two Scheme procedures.

Procedure vector-set! changes the value stored in a designated location within a vector, using the form:


(vector-set! vect index new-value)
That is, within vector vect, the element at the given index is changed to the specified new-value.

As the following examples indicate, procedure vector-set! itself does not return a new value -- rather it changes parameter vect.

  1. Type in the following sequence, and explain what is returned at each step:
    
    (define x #(3 #\a "fred" 0.31894 12/5))
    x
    (vector-set! x 3 "susan")
    x
    (vector-set! x 1 3.141592)
    x
    (define f
        (lambda (y)
         (vector-set! y 4 15)))
    (f x)
    x
    (vector-set! #(1 2 3 4 5 6) 3 10)
    (define y #(1 2 3 4 5 6))
    (vector-set! y 3 10)
    y
    
Again, it is important to emphasize that vector-set! need not return a useful value. (Standard Scheme does not specify what is value returned.) Instead, the vector parameter to vector-set! changes. Further, this change even occurs when vector-set! is applied within another function -- x changes in the call (f x), since f in turn calls vector-set!.

Similarly, procedure vector-fill! 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
(vector-fill! x "henry")
x
(vector-set! 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


(print-vector-length #f)
In subsequent lines, vectors will be printed showing each component.
  1. After using the print-vector-length procedure as shown, try the above sequence (with vector-fill!) to see this alternative output.

To restore the previous format for printing vectors, type

(print-vector-length #t)
Convention: 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.

  1. Review the examples for vector-fill!, and write a couple of sentences explaining the result of each Scheme command.

  2. Define a Scheme procedure named vector-iota 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.
    (vector-iota 9) ===> #9(0 1 2 3 4 5 6 7 8)
    (vector-iota 2) ===> #2(0 1)
    (vector-iota 0) ===> #0()
    
Structure Mutation Procedures vector-set! and vector-fill! illustrate a category of procedures that modify one of their parameters. Other procedures in this category include string-set!, set-car! and set-cdr!.
  1. To gain experience with these mutator procedures, try the following sequence of commands:
    
    (define str "abcdefg")
    str
    (string-set! str 3 #\q)
    str
    (define lst '(a b c d e f g h i))
    lst
    (set-car! lst 5)
    lst
    (set-cdr! lst '(3.14159 12/4 "string"))
    lst
    
    In each case, describe how the procedure changes the first parameter.

These procedures are analogous to the assignment operator (= or :=) in other programming languages. Changing the value of a variable is a side-effect (an effect of a computation other than returning a value). The ! emphasizes that the procedures have a side-effect.

For those that know BASIC, Pascal, C, or C++, note that Scheme's vector is analogous to an array, except that Scheme does not require that all elements in the vector have the same type. Thus, in the example #(3 #\a "fred" 0.31894 12/5), a single vector contains a character, a string, a real number, and a fraction.

  1. In a previous lab, we wrote a procedure to construct a list of the first n powers of 2. Now, write a procedure vector-powers-of-2 which takes an integer n as a parameter and returns a vector of the first n powers of 2 (i.e., 1, 2, ..., 2n-1. Thus,

    
    (vector-powers-of-2 5) ==> #(1 2 4 8 16)
    
  2. Write a procedure vector-to-zero which takes a vector as a parameter and changes all negative numbers in the vector to 0.


This document is available on the World Wide Web as

http://www.math.grin.edu/~walker/courses/151.fa00/lab-structure-mut.html

created April 3, 1997
last revised November 10, 2000