> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-security-edits.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# FunC types

export const Image = ({src, darkSrc, alt = '', darkAlt, href, target, height = 342, width = 608, noZoom = false, center = false}) => {
  const isSVG = src.match(/\.svg(?:[#?].*?)?$/i) !== null;
  const shouldInvert = isSVG && !darkSrc;
  const shouldCreateLink = href !== undefined;
  const minPx = 9;
  const maxPx = 608;
  const expectedPx = `a number or a string with a number that is greater than ${minPx - 1} and less than or equal to ${maxPx}`;
  const createInvalidPropCallout = (title, received, expected) => {
    return <Danger>
        <span className="font-bold">
          Invalid <code>{title.toString()}</code> passed!
        </span>
        <br />
        <span className="font-bold">Received: </span>
        {received.toString()}
        <br />
        <span className="font-bold">Expected: </span>
        {expected.toString()}
        {}
      </Danger>;
  };
  const checkValidDimensionValue = value => {
    switch (typeof value) {
      case "string":
      case "number":
        const num = Number(value);
        return Number.isSafeInteger(num) && num >= minPx && num <= maxPx;
      default:
        return false;
    }
  };
  let callouts = [];
  if (height && !checkValidDimensionValue(height)) {
    callouts.push(createInvalidPropCallout("height", height, expectedPx));
  }
  if (width && !checkValidDimensionValue(width)) {
    callouts.push(createInvalidPropCallout("width", width, expectedPx));
  }
  if (callouts.length !== 0) {
    return callouts;
  }
  const heightPx = Number(height);
  const widthPx = Number(width);
  const shouldCenter = center === "true" || center === true ? true : false;
  const shouldNotZoom = noZoom === "true" || noZoom === true ? true : false;
  const images = <>
      <img className="block dark:hidden" src={src} alt={alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
      <img className={`hidden dark:block ${shouldInvert ? "invert" : ""}`} src={darkSrc ?? src} alt={darkAlt ?? alt} {...height && ({
    height: heightPx
  })} {...width && ({
    width: widthPx
  })} {...(shouldCreateLink || shouldInvert || shouldNotZoom) && ({
    noZoom: "true"
  })} />
    </>;
  if (shouldCreateLink) {
    if (shouldCenter) {
      return <div style={{
        display: "flex",
        justifyContent: "center"
      }}>
          <a href={href} target={target ?? "_self"}>
            {images}
          </a>
        </div>;
    }
    return <a href={href} target={target ?? "_self"}>
        {images}
      </a>;
  }
  if (shouldCenter) {
    return <div style={{
      display: "flex",
      justifyContent: "center"
    }}>{images}</div>;
  }
  return images;
};

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>
    </>;
};

<Aside type="note">
  The official smart contract language of TON Blockchain is [Tolk](/tolk/overview). FunC is now a **legacy** language, with its compiler no longer maintained.

  FunC pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement, right between "Blockchain foundations" and "Contribute" sections:

  <Image src="/resources/images/tmp-func-fift-light.png" darkSrc="/resources/images/tmp-func-fift-dark.png" alt="Preview of a possible future placement of FunC and Fift languages in the sidebar." width={294} height={190} noZoom={true} />

  Learn how to [migrate from FunC to Tolk](/tolk/from-func/tolk-vs-func).
</Aside>

FunC offers a range of built-in types covering all the types the TVM has. On the other hand, FunC has no custom user-defined types like records or classes.

## Atomic types

Each of these types occupies a single entry on the [TVM stack](/tvm/overview#tvm-state).

|           |                                                                                                                                                                                                                                                                                 |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `int`     | a 257-bit signed integer type. Overflow checks are enabled by default and trigger an exception.                                                                                                                                                                                 |
| `cell`    | a [TVM cell type](/foundations/serialization/cells) for persistent data storage on TON Blockchain. Data is organized in a [bag of cells](/foundations/serialization/boc), with each cell containing up to 1023 bits of arbitrary data and up to four references to other cells. |
| `slice`   | a read-only view of a cell that allows sequential access to its data and references. A cell can be converted into a slice, extracting stored bits and references without modifying the original cell.                                                                           |
| `builder` | a mutable structure used to construct cells by adding data and references before finalizing them into a new cell.                                                                                                                                                               |
| `tuple`   | an ordered collection of up to 255 elements, each capable of holding a value of any type.                                                                                                                                                                                       |
| `cont`    | a [TVM continuation](/tvm/continuations) employed for execution flow management in [TVM instructions](/tvm/instructions).                                                                                                                                                       |

### Special null value

Any atomic type allows the special value `null` which represents the absence of an actual value of that type. For example, a function that searches the position of an integer in a list may return `null` to signify that it could not find the integer.

The `null` value can be obtained by calling the function [`null()`](/languages/func/stdlib#null). For example, in this snippet, an integer variable is declared and initialized with `null`:

```func 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"]}}
int a = null();   ;; a has value null
```

Since `null` is a valid value for any atomic type, keep the following in mind when working with functions:

* Functions that return an atomic type may return `null`.
* Functions that expect an atomic type as input could also accept `null`.
* For [library functions](/languages/func/stdlib) specifications explicitly indicate when `null` is acceptable as a valid input or output.

Example: [`cell_depth(cell c)`](/languages/func/stdlib#cell-depth) receives a `cell` as input, and its specification states that if the input cell is `null`, the function returns `0`.

### No boolean type

FunC does not have a boolean type. Instead, booleans are represented as integers:

* `false` is `0`, `true` is `-1`, a 257-bit integer with all bits set to `1`.
* Logical operations are performed using [bitwise operations](/languages/func/operators).
* In [conditional statements](/languages/func/statements#conditional-statements), [loops](/languages/func/statements#loops), and [conditional expressions](/languages/func/operators#ternary%2C-%3F%3A) any nonzero integer is regarded as `true`.

## Typed holes

FunC supports type inference through the type holes: `_` and `var` serve as placeholders resolved during type checking; `_` is for functions, and `var` is for variables.

Example:

```func 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 x = 2;
```

The type checker determines that `x` is of type `int` since `2` is an `int`.

As another example, in the following function declaration:

```func 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"]}}
_ someFunction(int a) {
  return a + 1;
}
```

the type checker infers that `_` has type `int`, as the return expression `a + 1` is of type `int`.

See [Function declarations](/languages/func/functions#function-declaration) for more details.

## Composite types

To represent non-atomic, composite types, simpler types can be combined with the following three operations.

### Function type

A functional type is written in the form `A -> B`, where:

* `A` is the input type, which is called domain.
* `B` is the output type, which is called codomain.

For example, the type `int -> cell` represents a function that:

* Takes an integer as input.
* Returns a cell as output.

Like in functional programming, it is possible to declare function types which have in their domain and codomain other function types. For example, `(int -> int) -> int` is a function with domain `int -> int` and codomain `int`. Similarly, `cell -> (slice -> slice)` is a function with domain `cell` and codomain `slice -> slice`

### Tuple type

Tuple types in FunC are written in the form `[A, B, ...]` and represent TVM tuples with fixed length and known component types at compile time. A tuple occupies one entry on the TVM stack, even if it is a zero-length tuple.

For example, `[int, cell]` defines a tuple with exactly two elements:

* The first element is an integer.
* The second element is a cell.

The type `[]` represents an empty tuple. There is only one value of this type, the empty tuple, which is also written as `[]`.

<Aside>
  The empty tuple `[]` occupies one stack entry.
</Aside>

### Tensor type

Tensor types represent ordered collections of values and are written in the form `(A, B, ...)`. These types occupy multiple TVM stack entries, unlike atomic types, which use a single entry.

**Example:**

A function `foo` of type `int -> (int, int)` takes one integer as input and returns two integers as output, each one occupying a stack entry.

Example call:

```func 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"]}}
(int a, int b) = foo(42);
```

Internally, the function consumes one stack entry and produces two.

**Type representation:**

Values `(2, (3, 9))` of type `(int, (int, int))` and `(2, 3, 9)` of type `(int, int, int)` are stored identically as three stack entries containing the values `2`, `3`, and `9`, respectively. However, FunC treats `(int, (int, int))` and `(int, int, int)` as distinct types. The following code **will not compile**:

```func 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"]}}
(int a, int b, int c) = (2, (3, 9));
```

However, this code will compile correctly:

```func 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"]}}
(int a, (int b, int c)) = (2, (3, 9));
```

FunC enforces strict type consistency, so only matching tensor structures are allowed.

<Aside>
  Exception: a type of the form `(A)` is considered by the type checker as the same type as `A`.
</Aside>

**Special case: unit type`()`**

The unit type `()` is used to indicate that:

* A function does not return a value, or
* A function takes no arguments

The unit type `()` has a single value, also written as `()`, occupying **zero** stack entries.

**Examples**

* `print_int` has the type `int -> ()`, meaning it takes an integer but returns nothing.
* `random` has the type `() -> int`, meaning it takes no arguments but returns an integer.

## Polymorphism with type variables

FunC supports [polymorphic functions](https://en.wikipedia.org/wiki/Parametric_polymorphism).

Example:

```func 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"]}}
forall X -> (X, X) duplicate(X value) {
  return (value, value);
}
```

Here, `X` is a type variable that allows the function to operate on values of any type. Type variables are declared between `forall` and `->`.

The function receives a value of type `X`, and duplicates this value to return a value of type `(X, X)`.

For example,

* Calling `duplicate(6)` produces `(6, 6)`.
* Calling `duplicate([])` produces two copies of an empty tuple: `([], [])`.

<Aside>
  Type variables in polymorphic functions cannot be instantiated with tensor types. The only exception is a tensor of a single element `(a)`, where `a` is not a tensor type itself. The compiler treats `(a)` as equivalent to `a`.
</Aside>

For more details, see the [Polymorphism with forall](/languages/func/functions#polymorphism-with-forall) section.

## User-defined types

FunC does not support defining custom types beyond the type constructions described above.

## Type width

Every value in FunC occupies a certain number of stack entries. If this number is consistent for all values of a given type, it is called the **type width**.

For example, all [atomic types](#atomic-types) have a type width of 1, because all their values occupy a single stack entry. The tensor type `(int, int)` has type width 2, because all its values occupy 2 stack entries.
