Tuples and Vectors

Tuples

A tuple is a fixed-length, heterogeneous sequence of values.

Source: Primitive types

Syntax

export pure circuit tupleSyntax(hash: Bytes<32>): [Uint<64>, Boolean] {
    // Tuple type: [T1, T2, ...]
    const pair: [Uint<64>, Boolean] = [100, true];
    const triple: [Field, Uint<8>, Bytes<32>] = [42, 255, hash];
    return pair;
}

Tuple values are created with [e1, e2, ...] syntax.

Source: Tuple creation

The Unit Type []

The empty tuple [] is called the unit type. It’s commonly used as the return type for circuits that don’t return a value:

export circuit doSomething(): [] {
    // perform operations
}

Source: Writing a contract

Tuple Element Access

Access tuple elements using bracket notation with a numeric literal:

export pure circuit access(): Uint<64> {
    const pair: [Uint<64>, Boolean] = [100, true];
    const first = pair[0];   // 100
    const second = pair[1];  // true
    return first;
}

Note: The index must be a numeric literal known at compile time.

Source: Element and member access expressions

Default Values

The default value of a tuple is a tuple where each element has its type’s default value:

  • [Uint<64>, Boolean] defaults to [0, false]

Source: Default values


Vectors

Vector<n, T> is a shorthand for a tuple of n elements all of type T. It’s exactly the same type as [T, T, ..., T] (n times).

Source: Primitive types

Syntax

export pure circuit vectors(): Vector<5, Uint<8>> {
    // Vector<n, T> is shorthand for [T, T, ..., T]
    const nums: Vector<5, Uint<8>> = [1, 2, 3, 4, 5];
    const flags: Vector<3, Boolean> = [true, false, true];

    // These are equivalent types:
    // Vector<3, Field> === [Field, Field, Field]
    return nums;
}

Vector Element Access

Same as tuples—use bracket notation with a numeric literal:

export pure circuit pick(): Uint<8> {
    const nums: Vector<5, Uint<8>> = [1, 2, 3, 4, 5];
    const third = nums[2];  // 3
    return third;
}

Source: Element and member access expressions

Vectors and Tuples Subtyping

The relationship between vectors and tuples follows these rules:

  • A tuple type [T, ...] has a vector type Vector<n, S> when a least upper bound S exists for all element types
  • When a tuple has a vector type, the tuple is a subtype of that vector type
  • A vector type Vector<n, T> is a subtype of a tuple type [S, ...] of length n if T is a subtype of each S

This means a vector can be passed where a compatible tuple is expected:

pure circuit processPair(p: [Uint<8>, Uint<8>]): Uint<16> {
    return ((p[0] as Uint<16>) + (p[1] as Uint<16>)) as Uint<16>;
}

export circuit example(): Uint<16> {
    const v: Vector<2, Uint<8>> = [10, 20];
    return processPair(v);  // Vector passed as tuple
}

Source: Subtyping and least upper bounds

TypeScript Representation

Both tuples and vectors are represented as TypeScript tuples or arrays:

// Compact: [Uint<64>, Boolean]
// TypeScript: [bigint, boolean]

// Compact: Vector<5, Uint<8>>
// TypeScript: bigint[]

Source: Representations in TypeScript

Exercises

Complete exercises/04_compound/01_tuples_vectors/.