> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/tolk/types/tuples",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Arrays and tuples

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

In [TVM](/tvm/overview), a tuple is a dynamic container that stores from 0 to 255 elements in a [single stack slot](/languages/tolk/types/overall-tvm-stack). Tolk provides several types built on top of TVM tuples:

* `array<T>` — a dynamically sized array of elements of type `T`.
* `[T1, T2, ...]` — a shaped tuple with a fixed number of elements of known types.
* `tuple` — an alias for `array<unknown>`, a legacy name for an untyped dynamic container.

<Aside type="caution">
  In many general-purpose languages, syntax `[A, B, C, ...]` is used for array or list literals, while syntax `(A, B, C, ...)` is used for tuples. However, in TON, there are no traditional arrays or lists. The `[A, B, C, ...]` syntax creates arrays or shaped tuples, while `(A, B, C, ...)` is used by [tensors](/languages/tolk/types/tensors): a distinct type that represents ordered collections of values that occupy multiple TVM stack entries.

  For example, `array<int>` is a single stack entry containing multiple integers. In contrast, a tensor `(int, int, int)` signifies three separate integers that occupy individual stack entries or are serialized sequentially.
</Aside>

## Arrays

`array<T>` is a dynamically sized container that holds elements of type `T`:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
array<int>
array<int?>
array<Point>
array<int | slice>
array<array<bool>>
```

### Creating arrays with `[...]`

Use `[...]` to create an array:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// array<int>
var numbers = [1, 2, 3];

// array<unknown>
var empty = [];

// array<int?>
var optionals = [1, null, 3];

// array<array<int>>
var matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];
```

To force a certain type `T` over `unknown` for empty arrays, specify it manually:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var nums: array<int> = [];
// or
var nums = array<int> [];
```

The syntax `array<int> [...]` is similar to the syntax of object creation with `Point {...}`, where a type hint may be omitted if clear from context.

If types within `[...]` are incompatible, a compilation error is reported:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// invalid:
var arr = [1, "aba"];
// error: type of `[...]` is `array<int | string>`;
//        probably, it's not what you expected

// valid:
var arr: array<unknown> = [1, "aba"];
// or
var arr: array<int | string> = [1, "aba"];
```

### Array methods

Arrays have several commonly-named methods. An IDE suggests them after a dot:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var nums = [] as array<int>;
nums.push(10);
nums.push(20);
nums.push(30);
nums.get(1);   // 20
nums.first();  // 10
nums.pop();    // 30
nums.size();   // 2 (pop removed the last element)

[1, 2, 3].last();  // 3
```

Additional methods such as `array.set` and others are [available in the standard library](/languages/tolk/features/standard-library#arrays).

### `T` can be any type

An array supports any element type, including structures and unions:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Point {
    x: int
    y: int
}

fun getArr(): array<Point> {
    return [
        { x: 10, y: 20 },
        { x: 50, y: 60 },
    ];
}
```

The compiler automatically packs complex items into sub-tuples. At the TVM level:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var arr = getArr();
// stack: [ [ 10 20 ] [ 50 60 ] ]

arr.get(0);
// stack: 10 20 (automatically un-tupled)

arr.get(0).y;
// stack: 20
```

The limit of 255 elements does not change regardless of `T`.

### Internally backed by TVM tuples

An array can contain from 0 to 255 elements. It occupies one stack slot regardless of its inner size. Accessing the first 16 elements consumes less gas than greater indices, because for `i >= 16` an additional instruction is required.

### Arrays are assignable to each other

An `array<T1>` can be assigned to `array<T2>` when `T1` is assignable to `T2`. The compiler handles all runtime transitions if required:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun demo(in: array<int>) {
    // ok, no runtime transitions needed
    var a1: array<int?> = in;

    // ok, but with runtime transitions
    var a2: array<int | slice> = in;
}
```

As a result, any `array<T>` can be assigned to `array<unknown>` directly.

## The `unknown` type

`unknown` represents one TVM primitive with contents unknown at compile time. Any type `T` can be cast to `unknown` and back using the `as` operator. If `T` is a primitive itself, this is a type-only cast. Otherwise, the object is packed into a sub-tuple and stored as a single slot:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var u1 = 5 as unknown;
// stack: 5
u1 as int;
// stack: 5

var u2 = (10, 20) as unknown;
// stack: [ 10 20 ] (a TVM tuple)
u2 as (int, int);
// stack: 10 20 (two integers)
```

Storing an element inside `array<T>` is effectively converting `T` to `unknown` followed by writing that slot into a TVM tuple.

## The `tuple` type

`tuple` is an alias for `array<unknown>`:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// declared in stdlib
type tuple = array<unknown>
```

Because of that, `tuple` has all the array methods: `push`, `size`, and others. Such arrays are opaque, so the `push` method accepts values of any type:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var t = [];   // array<unknown>
t.push(1);
t.push(null);
t.push(Point { x: 10, y: 20 });
// stack: [ 1 null [ 10 20 ] ]
```

Getter methods like `t.get()` and `t.first()` return `unknown`. To perform meaningful operations, cast the result to a known type:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var one = t.first();  // unknown
one + 123;            // error, can not apply operator `+`

// cast at reading
var one = t.first() as int;
one + 123;            // ok, 124
```

## Shaped tuples

Besides `array<T>` with a dynamic size, Tolk has fixed-size containers with a known shape, called *shaped tuples*: `[T1, T2, ...]`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var intAndStr: [int, string] = [1, "aba"];
// or
var intAndStr = [1, "aba"] as [int, string];
```

Shaped tuples differ from arrays:

* They do not have methods like `push`, `get`, or `pop`.
* They support indexed access: `value.0`, `value.1`, etc.
* Each element can have a different type.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var pair: [int32, Point] = [1, { x: 10, y: 20 }];
// stack: [ 1 [ 10 20 ] ]

var point = pair.1;
// stack: 10 20
```

A shaped tuple may be destructured into multiple variables:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun sumFirstTwo(t: [int, int, builder]) {
    val [first, second, _] = t;
    return first + second;
}
```

## The `[...]` constructor

The literal `[...]` is a universal constructor that creates different types depending on context. By default, it creates an array. If the target type is known, it creates that type:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// no hint — infer `array<int>`
var arr = [1, 2, 3];

// explicit array types
var tuple: array<unknown> = [1, 2, 3];
var optionals: array<int?> = [1, 2, 3];

// shaped tuple
var shape: [int, int, int?] = [1, 2, 3];

// lisp list
var list: lisp_list<int> = [1, 2, 3];

// empty map
var m: map<int32, address> = [];
```

The behavior is identical to creating an object with `{ ... }`: a type hint may exist on the variable, or the `Type [...]` syntax may be used:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// analogy between {...} and [...]
var p: Point = { ... };
var a: array<int> = [ ... ];

// the same — but on the right
var p = Point { ... };
var a = array<int> [ ... ];
```

This also works in function parameters, struct fields, and assignments.

## Lisp-style lists

`lisp_list<T>` is a set of nested two-element TVM tuples. For instance, `[1, [2, [3, null]]]` represents the list `[1, 2, 3]`.

Unlike `array<T>`, a lisp list can store more than 255 elements, because TVM tuples are not limited in depth. This is typically the only reason to use them: when output from a get method may grow unpredictably.

To use lists, import the `@stdlib/lisp-lists` file:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
import "@stdlib/lisp-lists"
```

Lisp lists allow accessing only the front element (head). There is no `array.get(i)` or cheap `array.size`:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var list = lisp_list<int> [];
list.prependHead(1);
list.prependHead(2);
list.prependHead(3);
// list is now "3 2 1"
// stack: [3 [2 [1 null]]]

var front = list.popHead();  // 3
// list is now "2 1"
```

Similarly, `T` can be any type: complex types like `Point` are represented as a single slot with an intermediate conversion to `unknown`.

Several helper methods are available in the standard library, such as `array.calculateSize` and `array.calculateConcatenation`. These have O(N) complexity: the longer the list, the higher the gas consumption.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
val depth = list.calculateSize();
```

If there is a clear upper bound on the number of elements, prefer [arrays](/languages/tolk/types/tuples#arrays) or [maps](/languages/tolk/types/maps). Otherwise, consider [contract sharding](/contract-dev/contract-sharding).

## Conversion between arrays and composites

For composite types, generic built-in methods `T.toTuple()` and `T.fromTuple()` convert composites to and from tuples. The length of the resulting tuple equals the number of stack slots occupied by the converted type:

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Point3d {
    x: int
    y: int
    z: int
}

fun demo(p: Point3d) {
    val t = p.toTuple();       // a tuple with 3 elements
    t.get(2) as int;           // z
    p = Point3d.fromTuple(t);  // back to a struct
}
```

## Stack layout and serialization

* `array<T>` and `tuple` occupy a single stack slot: a TVM `TUPLE`.
* Shaped tuples `[T1, T2, ...]` also occupy a single TVM `TUPLE` slot.
* `unknown` occupies a single stack slot.

Arrays can be [serialized to cells](/languages/tolk/types/overall-serialization) when `T` is serializable. The binary format uses snake references: a `uint8` length followed by chained cell references containing the elements.

Raw tuples are not serializable to cells, because `unknown` is unserializable. But they can be returned from [get methods](/tvm/get-method#get-methods), since contract getters operate directly on the stack.
