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

# Lion expression model: JSON as code

> Lion expressions are plain JSON values — primitives, arrays, and objects — each with distinct evaluation rules that make JSON directly executable.

Lion's expression model is the foundation of the language: every program is a valid JSON value. There is no separate syntax to learn, no parser to invoke, and no serialization step. Numbers, booleans, `null`, strings, arrays, and objects are all Lion expressions, each evaluated according to its own rules. This homoiconic design means programs can be stored in databases, sent over HTTP, and generated by other systems — because they are already data.

<Tabs>
  <Tab title="Primitives">
    Numbers, booleans, and `null` are **self-evaluating** — they return themselves unchanged. Strings are treated as **environment references**: if the string matches a key in the current environment the bound value is returned; if no binding exists the string returns as-is.

    ```json theme={null}
    42
    ```

    Evaluates to `42`.

    ```json theme={null}
    true
    ```

    Evaluates to `true`.

    ```json theme={null}
    null
    ```

    Evaluates to `null`.

    ```json theme={null}
    "x"
    ```

    With `{ "x": 10 }` in the environment, evaluates to `10`. With no binding, evaluates to `"x"`.

    ```json theme={null}
    "number/add"
    ```

    Resolves to the stdlib addition function because `stdlib` contains a `"number/add"` key.
  </Tab>

  <Tab title="Arrays">
    Arrays are **always executable expressions**. The evaluator first checks whether the head element is a known special-form keyword. If it is, the matching special-form handler runs. Otherwise the head is evaluated to a function and called with the evaluated tail as arguments.

    **Special form (define):**

    ```json theme={null}
    ["define", "x", 42]
    ```

    Stores `42` under `"x"` in the global environment and returns `42`.

    **Function call:**

    ```json theme={null}
    ["number/add", 1, 2]
    ```

    Resolves `"number/add"` from the environment, evaluates `1` and `2`, then calls the function — returns `3`.

    **Nested calls:**

    ```json theme={null}
    ["number/add", ["number/multiply", 2, 3], 4]
    ```

    Inner call returns `6`, outer call returns `10`.

    **Empty array:**

    ```json theme={null}
    []
    ```

    Evaluates to `[]` — an empty array is the one executable expression that passes through unchanged.
  </Tab>

  <Tab title="Objects">
    Objects **preserve their keys** and **evaluate each value recursively**. The result is a new object with the same key set but with every value replaced by its evaluated form. Keys are never evaluated.

    ```json theme={null}
    {
      "sum": ["number/add", 1, 2],
      "ok": true
    }
    ```

    Evaluates to:

    ```json theme={null}
    {
      "sum": 3,
      "ok": true
    }
    ```

    **Deeply nested:**

    ```json theme={null}
    {
      "stats": {
        "total": ["number/add", 10, 20],
        "doubled": ["number/multiply", 2, 15]
      }
    }
    ```

    Evaluates to:

    ```json theme={null}
    {
      "stats": {
        "total": 30,
        "doubled": 30
      }
    }
    ```

    <Note>
      Object keys must be non-empty strings. The key `"__proto__"` is disallowed by the schema to prevent prototype-pollution attacks on the host JavaScript environment.
    </Note>
  </Tab>
</Tabs>

## Expression schema

Internally, Lion validates every value against the `LionExpressionSchema` before evaluation begins. The schema is a union of three branches:

```typescript theme={null}
export const LionExpressionSchema = Schema.Union(
  JsonPrimitiveSchema,        // number | boolean | null | string
  LionArrayExpressionSchema,  // readonly LionExpression[]
  LionRecordExpressionSchema  // { [key: string]: LionExpression }
);
```

Anything that does not conform — such as a JavaScript `Date`, `undefined`, or a class instance — is rejected at the boundary before evaluation starts.
