The Vector Data Type in Racket
Vectors
The vector is the second primitive aggregate data type we use in Racket this semester. It can be used to build data structures that look like either arrays or records. Do you know the difference between arrays and records?
Other programming languages usually provide aggregate data types that provide for direct access to items either by name (records, structures) or by position (array, vector). Records usually provide access to items using field names and are heterogeneous, -- that is, they can contain items of different types. Arrays, on the other hand, provide access to items by their position in the aggregate and are homogeneous -- that is, all items must be of the same type.
Racket provides neither of these types, but its vector
data type can be used to simulate both. A vector provides
direct access to its elements by position, like an array.
But, like most things in Racket, it is dynamically typed and
so can contain elements of arbitrary type, like a record.
Those of you who know Python have already worked with a data structure serving dual purposes like this. A Python list is a heterogenous linked list whose elements can be accessed by position. We use it in place of arrays in many programs.
You should find that vectors feel rather familiar to you, based on your programming experiences in other languages. By now, the Racket syntax itself should not be causing too many problems. But be sure to spend a few minutes playing with vectors so that you can use them with ease later on.
The printed representation of Racket vectors in Dr. Racket is
#( ... )
. The #
character
distinguishes a vector from a list. You can create vector
literals in programs using this form, or you can use the
constructor function vector
:
> (vector 1 2 3) #(1 2 3) > (define 1-to-3 #(1 2 3)) > (define also-1-to-3 (vector 1 2 3)) > (define another-1-to-3 #3(1 2 3)) > 1-to-3 #(1 2 3) > also-1-to-3 #(1 2 3) > another-1-to-3 #(1 2 3)
Items in a vector can be accessed by position using the function
vector-ref
:
> (vector-ref 1-to-3 1)
2
> (vector-ref 1-to-3 0)
1
> (vector-ref 1-to-3 3)
vector-ref: index is out of range
index: 3
valid range: [0, 2]
vector: '#(1 2 3)
(See, a vector behaves a lot like a Python list ...)
Notice two things about Racket vectors:
- The first item in a vector is in slot 0. We say that Racket vectors are "0-based". In this respect, vectors are like arrays in Python, Java, and C++.
- Accesses are bounds-checked -- at run-time, of course. In this respect, vectors are different from C arrays.
Review Exercise
Here are some questions to consider to see how well you are understanding vectors and their relationship to pairs and lists:
- What is the difference between a vector and a pair?
- What is the difference between a vector and a list?
- Can you think of other aggregation constructs in other languages?