> ## 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": "/languages/tl-b/syntax-and-semantics",
  "feedback": "Description of the issue"
}
```

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

</AgentInstructions>

# TL-B syntax and semantics

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">
  TL-B pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement within the "Blockchain foundations" section:

  <Image src="/resources/images/tmp-tlb-light.png" darkSrc="/resources/images/tmp-tlb-dark.png" alt="Preview of a possible future placement of the TL-B language in the sidebar." width={294} height={156} noZoom={true} />
</Aside>

## Syntax

Each line of a TL-B file is either a TL-B scheme (i.e., type declaration), a comment, or a blank line.

### TL-B Scheme

The TL-B scheme describes how to serialize a certain algebraic data structure into a binary format. Here are some examples:

<Image src="/resources/images/tlb-scheme.png" darkSrc="/resources/images/tlb-scheme-dark.png" alt="General syntax of TL-B schemas" />

In general, each TL-B scheme has the following structure:

* **Constructor** that consists of
  * optional constructor name;
  * tag: empty, `$` or `#`;
  * prefix code or `_`.

```tlb 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"]}}
bool_true$1;
transfer#5fcc3d14;
some#_;
_#_.
```

* **Fields definitions**, each of which consists of
  * optional field name (`ident`);
  * type expression (type-expr).

```tlb 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:(## 32);
src:MsgAddressInt;
```

* **Constraints**: optional expressions that restrict values which are instances of the `Nat` type.

```tlb 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"]}}
{ n <= 100 };
{ ~b = a + 10 };
{ anycast = 0 };
{ b >= c }.
```

* **Parameters declarations**: declare fields of types `#` (natural numbers) or `Type` (types of types) that may be used as parameters for parameterized types.
  Always framed by curly `{}` brackets.

```tlb 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"]}}
_ {x:#} my_val:(## x) = A x;
_ {X:Type} my_val:(## 32) next_val:X = A X;
```

* **Combinator name**: the right side of the TL-B scheme that represents the name of the defined combinator. Could be parameterized.

```tlb 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"]}}
_ = MsgAddrSmpl;

// Parameterized combinators
_ = Maybe X;
_ = Hashmap n X.
```

### Comments

The comments follow the same conventions as in C++.

```tlb 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"]}}
/*
This is
a comment
*/

// This is a single-line comment
```

## Semantics

From a high-level perspective, the **right-hand side** of each *scheme* is a type, either simple (such as `Bit` or `True`) or parametrized (such as `Hashmap n X`) and
the **left-hand side** describes a way to define, or even to serialize, a value of the type indicated in the right-hand side.

Below, we gradually describe each component of TL-B schemes.

### Constructors

Constructors define a combinator's type, including its state during serialization. Each constructor begins with the (possibly empty `_`) string name,
such as a `message` or `bool_true`, immediately followed by an optional constructor tag, such as `#_` or `$10`, which describes the
bitstring used to encode (serialize) the constructor in question.

Tags may be given in either **binary** (after a dollar sign) or **hexadecimal** notation (after a hash sign).
If a tag is not explicitly provided, the TL-B parser must compute a default 32-bit constructor tag by hashing with
the [CRC32 algorithm](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) the text of the scheme with `| 0x80000000` defining this constructor in a certain fashion. Therefore,
empty tags must be explicitly provided by `#_` or `$_`.

All constructor names must be distinct, and constructor tags for the same combinator must constitute a [prefix code](https://en.wikipedia.org/wiki/Prefix_code#:~:text=A%20prefix%20code%20is%20a,code%20word%20in%20the%20system.)
(otherwise the deserialization would not be unique), i.e., no tag can be a prefix of any other.

Also, there are size limitations:

* maximum number of constructors per type: `64`;
* maximum number of bits for a tag: `63`.

For example, each address in TON could be either an **internal** message or an **external**, see [general info page](/foundations/addresses/overview).
Addresses are serialized according to the following TL-B schemes:

```tlb 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"]}}
addr_none$00 = MsgAddressExt;
addr_extern$01 ... = MsgAddressExt;
addr_std$10 ...  = MsgAddressInt;
addr_var$11 ... = MsgAddressInt;
...

_ _:MsgAddressInt = MsgAddress;
_ _:MsgAddressExt = MsgAddress;
```

When parsing the binary string `10...` that should be an instance of `MsgAddress` combinator, the parser extracts the initial two bits that determine the tag.
It then understands that this address is further serialized as `add_std` and continues to parse our string relative to the fields defined in this constructor.

All main variations of constructors are presented in the following table:

| Constructor                 | Serialization                                   |
| --------------------------- | ----------------------------------------------- |
| `some#3f5476ca`             | A 32-bit `uint` is serialized from a hex value. |
| `some#5fe`                  | A 12-bit `uint` is serialized from a hex value. |
| `some$0101` or `_$0101`     | Serialize the `0101` raw bits.                  |
| `some` or `some#`           | Serialize `crc32(equation) \| 0x80000000`.      |
| `some#_` or `some$_` or `_` | Serialize nothing.                              |

In addition to the standard hex tag definition, a hexadecimal number may be followed by an underscore `_` character.
This indicates that the tag should be interpreted as the hexadecimal value with the [least significant bit (LSB)](https://en.wikipedia.org/wiki/Bit_numbering#Least_significant_bit) removed.
For example, consider the following schema, which represents a stack integer value:

```tlb 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"]}}
vm_stk_int#0201_ ... = VmStackValue;
```

In this case, the tag is not equal to `0x0201`. To compute the actual tag, remove the LSB from the binary representation of `0x0201`:

```
0000001000000001 -> 000000100000000
```

The resulting tag is the 15-bit binary number `0b000000100000000`.

### Field definitions

Field definitions follow each constructor and its optional tag. A field definition has the format `ident:type-expr`, where:

* `ident` is the field's name. If you don't want to assign a specific name to the field, just leave it as `_`.
* `type-expr` is the field's type. It can be a simple type, a parameterized type with appropriate arguments, or a more complex expression.

**Note: the total size of all fields in a type must not exceed the limits of a single cell:  `1023` bits and `4` references**.

TL-B schemes define types. At the same time, the previously defined types can be used in other schemes in fields.
Therefore, in order to properly understand what types can be assigned to fields, we need to simultaneously figure out how to define the types themselves.

### Types

#### Simple

Fields that are simple types are just examples of some previously defined or built-in types. They do not contain parameterization or any conditions.

For example, **Tick** and **Tock** transactions are designated for special system smart contracts that must be automatically invoked in every block.
Tick transactions are executed at the start of each masterchain block, while Tock transactions are initiated at the end. Here is how they are represented in TL-B:

```tlb 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"]}}
trans_tick_tock$001 is_tock:Bool storage_ph:TrStoragePhase
    compute_ph:TrComputePhase action:(Maybe ^TrActionPhase)
    aborted:Bool destroyed:Bool = TransactionDescr;
```

So, `is_tock`, `storage_ph`, `compute_ph`, `aborted`, and `destroyed` are fields with simple types.

Below are all the built-in types that can be used in defining fields:

* `#`: 32-bit unsigned integer;
* `## x`: unsigned integer with `x` bits;
* `#< x`: unsigned integer less than `x` bits, stored as `lenBits(x - 1)` bits up to 31 bits;
* `#<= x`: unsigned integer less than or equal to `x` bits, stored as `lenBits(x)` bits up to 32 bits;
* `Any` or `Cell`: remaining bits and references;
* `uint1`: `uint256` - 1 - 256 bits;
* `int1`: `int257` - 1 - 257 bits;
* `bits1`: `bits1023` - 1 - 1023 bits.

#### Contained complex expressions

* **Multiplicative expression for tuple creation**. The expression `x * T` creates a tuple of the natural length `x`, where each element is of type `T`.

```tlb 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"]}}
a$_ a:(## 32) = A;
b$_ b:(2 * A) = PairOf32-bits-uints;
```

* **Serialization in the ref cell**: `^[ ... ]` means that the fields inside the brackets are serialized in a separate cell, which is referenced from the current cell.

```tlb 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"]}}
_ a:(## 32) ^[ b:(## 32) c:(## 32) d:(## 32)] = A;
```

Chains of references are also allowed. In the following example, each variable (`a`, `b`, `c`) is stored in a separate cell, resulting in a chain of three referenced cells:

```tlb 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"]}}
_ ^[ a:(## 32) ^[ b:(## 32) ^[ c:(## 32) ] ] ] = A;
```

Other complex type expressions are related to the `Nat` type only. The `Nat` type is a built-in type that represents natural numbers.
The types `#`, `## x`, `#< x`, and `#<= x` together constitute the `Nat` type. In TL-B schemes, the `+` and `*` operations can be performed on `Nat`.

* **Constraints**: `Nat = Nat | Nat <= Nat | Nat < Nat | Nat >= Nat | Nat > Nat`. Each constraint must be enclosed in curly braces `{}`, and the variables used inside must be defined earlier.

```tlb 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"]}}
_ flag1:(## 10) flag2:# { flag1 + flag2 <= 100 } = Flag;
```

This constraint means that the sum of the flags fields must be less than or equal to `100`.

* **Condition operator**: `Nat?Type` means that if the natural number is positive, then the field has the type `T`. Otherwise, the field is omitted.

```tlb 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"]}}
_ a:(## 1) b:a?(## 32) = Example;
```

In the `Example` type, the field `b` is serialized only if the `a` field is equal to `1`.

* **Bit selector**: The expression `E . B` means to take bit `B` from the `Nat` value `E`.

```tlb 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"]}}
_ a:(## 2) b:(a . 1)?(## 32) = CondExample;
```

Similarly, in the `CondExample` type, the variable `b` is serialized only if the **second bit** of `a` is `1`.

For the real-world example, one may consider the following `McStateExtra` combinator that describes data stored in each masterchain block.

```tlb 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"]}}
masterchain_state_extra#cc26
  shard_hashes:ShardHashes
  config:ConfigParams
  ^[ flags:(## 16) { flags <= 1 }
     validator_info:ValidatorInfo
     prev_blocks:OldMcBlocksInfo
     after_key_block:Bool
     last_key_block:(Maybe ExtBlkRef)
     block_create_stats:(flags . 0)?BlockCreateStats ]
  global_balance:CurrencyCollection
= McStateExtra;
```

#### Parameterized

**Parameterized types** are patterns in which other types are parameters. Such parameters are declared in curly brackets `{}` or must be declared previously
as a combinator's field. Only identifiers of the `Nat` and `Type` types can be parameters.

A simple example of a parameterized type is the following definition of a type `A` that is parameterized by a natural number `x`:

```tlb 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"]}}
_ {x:#} my_val:(## x) = A x;
```

During the deserialization process, it fetches an x-bit unsigned integer. For example:

```
_ value:(A 32) = My32UintValue;
```

During the deserialization process of `My32UintValue`, it fetches a 32-bit unsigned integer, as specified by the `32` natural parameter in the `A` type.

Let's consider another example where a combinator `A` parameterized by a type variable `X` is defined:

```tlb 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"]}}
_ {X:Type} my_val:(## 32) next_val:X = A X;
```

During the deserialization process, we will first fetch a 32-bit unsigned integer and then parse the bits and references of the X type.

An example usage of such a parameterized type can be:

```tlb 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"]}}
_ bit:(## 1) = Bit;
_ 32intwbit:(A Bit) = 32IntWithBit;
```

In this example, the `Bit` type is passed to `A` as a parameter.

There is a possibility to use partial applications with such parameterized types:

```tlb 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"]}}
_ {X:Type} {Y:Type} v1:X v2:Y = A X Y;
_ bit:(## 1) = Bit;
_ {X:Type} bits:(A Bit X) = BitA X;
```

Or even apply partial application to parameterized types themselves:

```tlb 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"]}}
_ {X:Type} v1:X = A X;
_ {X:Type} d1:X = B X;
_ {X:Type} bits:(A (B X)) = AB X;
```

It is also possible to use fields defined previously as parameters to types. The serialization will be determined at runtime.

```tlb 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"]}}
_ a:(## 8) b:(## a) = A;
```

This means that the size of the `b` field is stored inside the `a` field. When serializing type `A`, we first load the 8-bit unsigned integer from the `a` field and then use this value to determine the size of the `b` field.

This strategy also works for parameterized types:

```tlb 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"]}}
_ {input:#} c:(## input) = B input;
_ a:(## 8) c_in_b:(B a) = A;
```

Since parameters can be natural numbers, one can use arithmetic operations on them:

```tlb 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"]}}
_ {x:#} value:(## x) = ExampleMult (x * 2);
_ _:(ExampleMult 4) = 2BitInteger;

_ {x:#} value:(## x) = ExampleSum (x + 3);
_ _:(ExampleSum 4) = 1BitInteger;
```

The good real-world example of parameterized types is the definition of TVM tuples:

```tlb 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"]}}
vm_tupref_nil$_ = VmTupleRef 0;
vm_tupref_single$_ entry:^VmStackValue = VmTupleRef 1;
vm_tupref_any$_ {n:#} ref:^(VmTuple (n + 2)) = VmTupleRef (n + 2);
vm_tuple_nil$_ = VmTuple 0;
vm_tuple_tcons$_ {n:#} head:(VmTupleRef n) tail:^VmStackValue = VmTuple (n + 1);
vm_stk_tuple#07 len:(## 16) data:(VmTuple len) = VmStackValue;
```

For a detailed explanation of how it works, see the [complex and non-trivial examples page](/languages/tl-b/complex-and-non-trivial-examples).

#### Special

Currently, TVM allows the following types of cells:

* Ordinary
* PrunedBranch
* Library
* MerkleProof
* MerkleUpdate

By default, all cells are classified and parsed as `Ordinary`. This applies to all cells described in the TL‑B as well.

To enable the loading of special types in the constructor, prepend `!` before the constructor.

**Example**

```tlb 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"]}}
!merkle_update#02 {X:Type} old_hash:bits256 new_hash:bits256
  old:^X new:^X = MERKLE_UPDATE X;

!merkle_proof#03 {X:Type} virtual_hash:bits256 depth:uint16 virtual_root:^X = MERKLE_PROOF X;
```

This technique allows code generation to mark `SPECIAL` cells when printing a structure and ensures proper validation of structures with special cells.

### Implicit fields and the negate operator (`~`)

Some fields may be **implicit**. These fields are defined within curly brackets `{}`, as constraints and parameters of the parametrized types,
indicating that they are not directly serialized. Instead, their values must be deduced from other data, usually the parameters of the type being serialized.

Some occurrences of the indicators already defined earlier in a scheme are prefixed by a tilde `~`. This indicates that the indicator's occurrence is used
oppositely from the default behavior. On the left-hand side of the equation, it means that the indicator is deduced (computed) based on this occurrence,
rather than substituting its type's defined value. Conversely, on the right-hand side, the indicator is not deduced from
the serialized type but instead computed during the deserialization process. In other words,
a `~` transforms an *input argument* into an *output argument* or vice versa.

A simple example of the negate operator is the definition of the implicit indicator `b` based on another indicator `a`:

```tlb 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"]}}
_ a:(## 32) { b:# } { ~b = a + 100 } = B_Calc_Example;
```

So, after deserialization of `a`, the value of `b` is computed as `a + 100`. After this definition, you can use the new indicator as input for `Nat` types:

```tlb 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"]}}
_ a:(## 8) { b:# } { ~b = a + 10 }
  example_dynamic_var:(## b) = B_Calc_Example;
```

The size of `example_dynamic_var` is computed at runtime when we load `a` and use its value to determine the size of `example_dynamic_var`.

Alternatively, it can be applied to other types:

```tlb 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"]}}
_ {X:Type} a:^X = PutToRef X;
_ a:(## 32) { b:# } { ~b = a + 100 }
  my_ref: (PutToRef b) = B_Calc_Example;
```

#### Negate operator (`~`) in type definition

```tlb 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"]}}
_ {m:#} n:(## m) = Define ~n m;
_ {n_from_define:#} defined_val:(Define ~n_from_define 8) real_value:(## n_from_define) = Example;
```

Assume we have a class `Define ~n m` that takes `m` and computes `n` by loading it from an `m`-bit unsigned integer.

In the `Example` type, we store the variable computed by the `Define` type into `n_from_define`. We also know it's an `8`-bit unsigned integer because we apply the `Define` type with `Define ~n_from_define 8`. Now, we can use the `n_from_define` variable for other kinds to determine the serialization process.

This technique leads to more complex type definitions, such as **Unions** that represent dynamic chains of some type.

```tlb 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"]}}
unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);
_ u:(Unary Any) = UnaryChain;
```

and **Hashmaps**.

```tlb 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"]}}
hm_edge#_ {n:#} {X:Type} {l:#} {m:#} label:(HmLabel ~l n)
          {n = (~m) + l} node:(HashmapNode m X) = Hashmap n X;

hmn_leaf#_ {X:Type} value:X = HashmapNode 0 X;
hmn_fork#_ {n:#} {X:Type} left:^(Hashmap n X)
           right:^(Hashmap n X) = HashmapNode (n + 1) X;

hml_short$0 {m:#} {n:#} len:(Unary ~n) {n <= m} s:(n * Bit) = HmLabel ~n m;
hml_long$10 {m:#} n:(#<= m) s:(n * Bit) = HmLabel ~n m;
hml_same$11 {m:#} v:Bit n:(#<= m) = HmLabel ~n m;

unary_zero$0 = Unary ~0;
unary_succ$1 {n:#} x:(Unary ~n) = Unary ~(n + 1);

hme_empty$0 {n:#} {X:Type} = HashmapE n X;
hme_root$1 {n:#} {X:Type} root:^(Hashmap n X) = HashmapE n X;
```

For a detailed explanation of how these combinators are deserialized, see the [complex and non-trivial examples page](/languages/tl-b/complex-and-non-trivial-examples).

## References

* [A description of an older version of TL](https://core.telegram.org/mtproto/TL);
* [`block.tlb`](https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb): the main TL-B file that describes all basic TON blockchain structures.
