8.8. 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.
8.8.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)
[<qualifier>] vector<|type|> |identifier|; [<qualifier>] vector<|type|> |identifier| = |type-expr|; [<qualifier>] 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] var vector<integer> v4 = 42; // [42], mutable vector<integer> v4 = 42; // [42], implied const const vector<real> v5 = 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[*]> padded_right = [[1.0, 2.0], [1.0]]; // Pads second element const vector<character> const_vec = vec;
8.8.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. All binary operations between vector and arrays produce array results.
As a language supported object, Gazprea provides several methods for vector:
push(T)- pushes a new element to the back of the vector, whereTis the element type of the vectorlen()- number of elements in the vectorappend(T[*])- append another array to the vector whereT[*]is the type of the original vector or a type that can be implicitly cast to it.var vector<integer> v1; // v1 == [] v1.len() -> std_output; // 0 v1.push(1); // v1 == [1] v1.len() -> std_output; // 1 v1.push(2); // v1 == [1, 2] v1.len() -> std_output; // 2 v1.append([3, 4, 5]) // v1 == [1, 2, 3, 4, 5] v1.len() -> std_output; // 5 var vector<real[2]> v2; // v2 == [] const x = 1..10; // `1` is promoted to `[1.0, 1.0]` before appending v2.append(1); // v2 == [[1.0, 1.0]] // length 1 array padded to length 2 v2.append([3.0]); // v2 == [[1.0, 1.0], [3.0, 0.0]] // slices v2.append(x[5..7]); // v2 == [[1.0, 1.0], [3.0, 0.0], [5.0, 6.0]] v2.len() -> std_output // 3 v2.len(); // Does nothing (v1 + v2).push(3); // Effectively does nothing, reference to the sum is dropped after the statement
Slicing a vector produces an array slice (there are no “vector slices”).
// Slicing a vector produces an array slice vec[2..5].append(x[5..7]) // TypeError; cannot do `append` on an array slice