# 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)`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kimlikdao.org/annotations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
