7.9. Vectors
Vectors are language supported objects that allow for dynamically sized arrays.
Once created, vectors in Gazprea behave exactly like arrays: they can be
intermixed with arrays in expressions; they can be used on the RHS of array
declarations and initializations; and they can be passed as array arguments to
subroutines and functions.
7.9.1. Declaration
Vectors are declared and (optionally) initialized as follows.
(Note that we have replaced <> with | in the notation below since
the literals < and > are used in the declaration)
vector<|type|> |identifier|; vector<|type|> |identifier| = |type-expr|; vector<|type|> |identifier| = |type-array|;
Unlike the array type, Gazprea vectors do not have an explicit size specifier, often called capacity in other languages. Below are some examples of vector declarations.
const vector<integer[2]> v1 = 3; // [[3, 3]] const vector<integer[2]> v2 = [4, 5]; // [[4, 5]] const vector<integer> v3 = 42; // [42] const vector<real> v4 = 1; // [1.0]
Vectors of inferred sized arrays assume the size of the first array in the vector.
Subsequent array elements of less than the inferred size are padded.
Those greater raise a runtime SizeError.
const vector<character> vec = ['a', 'b', 'c']; const vector<real[*]> ragged_right = [[1.0], [2.0, 2.0]]; // SizeError const vector<real[*]> paddeded_right = [[1.0, 2.0], [1.0]]; // Padds second element const vector<character> const_vec = vec;
7.9.2. Operations
Operations on vectors are identical syntactically and semantically to operations on arrays. In particular, operand lengths must match for binary expressions and dot product. Vectors can behave as arrays by using slices:
var vector<integer> v1, v2; var integer[3] a; v1.append([1, 2, 3]); a = v1; // slice of v yields array and can be used to initialize 'a' v2 = v1 + a; // slice of vector plus array yields result type array a = v1 + v2; // slice of v1 + slice of v2 still yields array type
A vector or vector slice can be passed as a call argument that has been declared as an array slice of the same size and type. When indexing a vector of arrays, the first index selects the array element within the vector, and the second index selects the element within the array:
vector<real[*]> ragged_right = [[1.0], [2.1]]; length(ragged_right[1]) -> std_output; // prints 1 ragged_right[2][1] -> std_output; // prints 2.1
As a language supported object, Gazprea provides several methods for vector:
push()- pushes a new element to the back of the vectorlen()- number of elements in the vectorappend(T[*])- append another array slice to the vector where T is the type of the original vector or a type that can be implicitly cast to it. The following example tracks the elements inside vec through various appends.const x = 1..10; var vector<real[2]> vec; // [] // scalar to array promotion vec.append(1); // [[1.0, 1.0]] // array padding vec.append(3..3); // [[1,0, 1.0], [3.0, 0.0]] // slices vec.append(x[5..7]); // [[1,0, 1.0], [3.0, 0.0], [5.0, 6.0]] vec[tvec.len()] -> std_output; // prints 3