> For the complete documentation index, see [llms.txt](https://docs.kimlikdao.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kimlikdao.org/annotations.md).

# Annotations

In kdts, compiler directives are provided via `satisfies` expressions, or when it's more convenient, through the `@satisfies {}` jsdoc tags.

### Overridable

Constant variable declarations can be annotated as `Overridable`. For such variables, the default initializer can be overridden with values supplied from the command line:

{% code title="worker.ts" %}

```typescript
import { Overridable } from "@kimlikdao/kdts";

const Status = 404 satisfies Overridable;
const HostUrl = "https://example.com" satisfies Overridable;

export default () => Response.redirect(HostUrl, Status);
```

{% endcode %}

When compiled with `kdts worker.ts --override HostUrl="test.com" --override Status=405`, we get

{% code title="worker.out.js" %}

```javascript
export default()=>Response.redirect("test.com",405);
```

{% endcode %}

### Function classes

In kdts, to achieve better optimizations, functions can be annotated as belonging to certain function classes. For example:

```typescript
/** @satisfies {PureFn} */
const greet = (name: string) => `Hi, ${name}!`;
```

Here, `greet` is annotated as being `PureFn` , which promises to the compiler that the function has no side effects, does not depend on mutable external state (hence deterministic) and returns a fresh value (we will introduce this formally later; primitives are always fresh).

If the function depended on external mutable state but is side-effect free, we can use the weaker marker `SideEffectFreeFn`:

```typescript
/** @satisfies {SideEffectFreeFn} */
const rand = (a: number, b: number) => a + Math.random() * (b - a);
```

An `InlineFn` is inlined to each call site and the function body is compiled away completely:

```typescript
/** @satisfies {InlineFn} */
const ensureArray = <T>(x: T | T[]): T[] => Array.isArray(x) ? x : [x];
```

Now, each time `ensureArray(x)` is called, we will see the expression `Array.isArray(x) ? x : [x]` inlined, unless kdts can prove x to be an array or not an array from the declared or inferred types. In such cases, the function call is compiled to `x` or `[x]` .

#### FreshValue

Before we go over all function classes, let us define `FreshValue` first. A `FreshValue` is defined recursively as a primitive (such as `string`, `number`, `bigint` etc) or a fresh object containing `FreshValue` s. For instance the following are all `FreshValue`s

```typescript
"Abc",
{ name: "Abc", age: 1 },
new Uint8Array([1, 2, 3]),
Uint8Array.fromHex("abcd").buffer,
```

The following is not a `FreshValue`

```typescript
const person = { name: "Abc", age: 1 };
{ person }
```

since `person` is not a fresh object.

#### List of function classes

Here is the full list of function annotations `kdts` currently optimizes with:

<table><thead><tr><th width="244.0078125">Annotation</th><th>Meaning</th></tr></thead><tbody><tr><td><code>DeterministicFn</code></td><td>A function which doesn't read external mutable state</td></tr><tr><td><code>SideEffectFreeFn</code></td><td>A function which doesn't change its argument or any external state</td></tr><tr><td><code>MethodFn</code></td><td>A class method which can only change state reachable from `this`. Further, it cannot read external mutable state.</td></tr><tr><td><code>InPlaceFn</code></td><td>A function which mutates only state reachable from its arguments. Further, it cannot read external mutable state.</td></tr><tr><td><code>InPlaceRandFn</code></td><td>A function which mutates only state reachable from its arguments. It can read external mutable state.</td></tr><tr><td><code>PureAliasFn</code></td><td>A function which doesn't read external mutable state and is side-effect free.</td></tr><tr><td><code>PureFn</code></td><td>A <code>PureAliasFn</code> which also returns a <code>FreshValue</code></td></tr><tr><td><code>InlineFn</code></td><td>A function which will be inlined to each call site and the function body will be compiled away.</td></tr><tr><td><code>NoInlineFn</code></td><td>A function which cannot be inlined and calls to it must be preserved as-is.</td></tr><tr><td><code>InlineFriendlyFn</code></td><td>A function the compiler is encouraged to inline when profitable, but unlike <code>InlineFn</code> it is not required to inline every call site.</td></tr></tbody></table>

#### Examples

```typescript
/**
 * Partitions the array into chunks of size n, except for the last chunk which
 * can be smaller, but not empty.
 *
 * For n ≤ 0, returns []
 *
 * @satisfies {PureFn}
 */
const chunk = <T>(arr: T[], n: number): T[][] => {
  if (n <= 0) return [];
  const result: T[][] = [];
  for (let i = 0; i < arr.length; i += n)
    result.push(arr.slice(i, i + n));
  return result;
};

/**
 * Shuffles the array uniformly at random in place.
 * @satisfies {InPlaceRandFn}
 */
const shuffle = <T>(arr: T[]): T[] => {
  for (let i = arr.length - 1; i > 0; --i) {
    const j = (Math.random() * (i + 1)) | 0;
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  return arr;
};

/** @satisfies {SideEffectFreeFn & NoInlineFn} */
const byId = (id: string): HTMLElement =>
  document.getElementById(id) as HTMLElement;
```

### LargeConstant

A constant variable declaration can be marked as a large constant; this will prevent it from being inlined to each use of it.

```typescript
import { LargeConstant } from "@kimlikdao/kdts";
import { arfCurve } from "@kimlikdao/lib/crypto/arfCurve";

const P = (1n << 254n) + 0x224698fc094cf91b992d30ed00000001n satisfies LargeConstant;
const Pallas: Curve = arfCurve(P, 5n);
```

### PureExpr

Marks an expression as side-effect free and deterministic.

```typescript
import { Overridable, PureExpr } from "@kimlikdao/kdts";
import { f, g } from "./util";

const KeepConsole = true satisfies Overridable;

const x = f(100 + g(5)) + f(g(2)) satisfies PureExpr;

if (KeepConsole)
  console.log(x);
```

Now kdts is free to eliminate the entire initializer expression of x. If \`KeepConsole=true\`, kdts is free to replace x with the evaluated result in `console.log(x)`.
