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

# Special forms reference: Lion's built-in syntax

> Lion's seven special forms — quote, eval, begin, define, lambda, cond, and match — cover all control flow and abstraction in the language.

Special forms are array expressions whose first element is a reserved keyword. Unlike ordinary function calls, special forms are recognized by the evaluator before argument evaluation occurs, giving them control over when and whether their sub-expressions are evaluated. Lion has exactly seven special forms, and together they are sufficient to express any computation the language supports.

<Accordion title="quote — return a value unevaluated">
  `quote` suppresses evaluation and returns its argument as a raw Lion value. It is the primary way to produce an array or string literal that should not be treated as a function call or an environment reference.

  **Syntax:** `["quote", <expression>]`

  **Returns:** the argument, unchanged.

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

  Returns the array `["number/add", 1, 2]` — not `3`.

  ```json theme={null}
  ["quote", "hello"]
  ```

  Returns the string `"hello"` regardless of whether `"hello"` is bound in the environment.

  <Tip>
    Use `quote` any time you need to treat an array as data rather than as a call. It pairs naturally with `eval` to implement deferred or code-generating programs.
  </Tip>
</Accordion>

<Accordion title="eval — evaluate twice">
  `eval` evaluates its argument and then evaluates the result a second time. This allows a Lion program to construct an expression at runtime and immediately execute it.

  **Syntax:** `["eval", <expression>]`

  **Returns:** the result of evaluating the produced expression.

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

  First pass: `quote` returns `["number/add", 1, 2]`.
  Second pass: that array is evaluated as a function call, returning `3`.

  Internally, `evaluateEval` validates the first-pass result against `LionExpressionSchema` before the second evaluation, so only valid Lion expressions can be double-evaluated.

  ```typescript theme={null}
  export const evaluateEval = ([_, args]: typeof EvalFormSchema.Type) =>
    pipe(
      evaluate(args),
      Effect.flatMap(Schema.decodeUnknown(LionExpressionSchema)),
      Effect.flatMap(evaluate)
    );
  ```
</Accordion>

<Accordion title="begin — sequential evaluation">
  `begin` evaluates a sequence of expressions in order and returns the value of the last one. It is the standard way to execute side-effecting forms (such as `define`) before producing a final result.

  **Syntax:** `["begin", <expr1>, <expr2>, ..., <exprN>]`

  **Returns:** the value of `<exprN>`.

  ```json theme={null}
  ["begin",
    ["define", "x", 1],
    ["define", "x", 2],
    "x"]
  ```

  Evaluates both `define` forms in order, then resolves `"x"` — returns `2`.

  ```json theme={null}
  ["begin",
    ["console/log", "step 1"],
    ["console/log", "step 2"],
    42]
  ```

  Logs both messages in order, returns `42`.
</Accordion>

<Accordion title="define — bind a name in the global environment">
  `define` evaluates an expression and stores the result under a name in the **toplevel** (global) environment. The stored value is also returned, making `define` composable inside `begin` chains.

  **Syntax:** `["define", "<name>", <expression>]`

  **Returns:** the evaluated value.

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

  Stores `42` under `"answer"` globally and returns `42`.

  ```json theme={null}
  ["define", "double",
    ["lambda", ["x"], ["number/multiply", "x", 2]]]
  ```

  Stores a lambda under `"double"`. Later expressions can call it:

  ```json theme={null}
  ["double", 5]
  ```

  Returns `10`.

  <Warning>
    `define` always writes to the **global** environment, not to the nearest enclosing scope. Use `lambda` parameters to introduce locally-scoped bindings.
  </Warning>
</Accordion>

<Accordion title="lambda — create a lexically-scoped function">
  `lambda` creates a Lion function. It captures the environment at definition time (lexical closure) and creates a fresh inner environment for each call, binding parameter names to the supplied arguments.

  **Syntax:** `["lambda", ["<param1>", "<param2>", ...], <body>]`

  **Returns:** a JavaScript function that, when called, evaluates `<body>` in the captured scope extended with the argument bindings.

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

  A function that adds 1 to its argument.

  ```json theme={null}
  [["lambda", ["x", "y"], ["number/multiply", "x", "y"]], 3, 4]
  ```

  Immediately-invoked lambda — returns `12`.

  **Closures:**

  ```json theme={null}
  ["begin",
    ["define", "base", 10],
    ["define", "addBase", ["lambda", ["n"], ["number/add", "base", "n"]]],
    ["addBase", 5]]
  ```

  Returns `15`. The lambda closes over `"base"` through the environment chain.

  Lambdas also observe `define` mutations made **after** creation, because they walk the environment chain at call time rather than copying values at definition time.
</Accordion>

<Accordion title="cond — conditional branching">
  `cond` evaluates condition/result pairs in order and returns the result of the first pair whose condition is truthy. An optional `else` branch acts as a catch-all. If no condition matches and no `else` is present, `cond` returns `null`.

  **Syntax:**

  ```json theme={null}
  ["cond",
    [<condition1>, <result1>],
    [<condition2>, <result2>],
    ["else", <default-result>]]
  ```

  **Returns:** the result of the first matching branch, or `null`.

  ```json theme={null}
  ["cond",
    [["number/greaterThan", "score", 90], "great"],
    [["number/greaterThan", "score", 70], "pass"],
    ["else", "retry"]]
  ```

  With `"score"` bound to `85`, the second branch matches — returns `"pass"`.

  **Without else:**

  ```json theme={null}
  ["cond",
    [false, "never"]]
  ```

  No branch matches — returns `null`.

  Conditions are evaluated lazily: as soon as one returns a truthy value, subsequent conditions are not evaluated.
</Accordion>

<Accordion title="match — structural pattern matching">
  `match` evaluates a value, tests it against a sequence of predicate/handler pairs, and calls the handler of the first matching pair with the value. The last argument is always a fallback handler that runs when no pattern matches.

  **Syntax:**

  ```json theme={null}
  ["match",
    <value-expression>,
    [<predicate1>, <handler1>],
    [<predicate2>, <handler2>],
    <fallback-handler>]
  ```

  **Returns:** the result of calling the matched handler with the value.

  ### Functional predicates

  Any function that returns a boolean can be a predicate. The stdlib `value/*?` functions are designed for this:

  ```json theme={null}
  ["match",
    "value",
    ["value/number?", ["lambda", ["x"], ["number/add", "x", 1]]],
    ["value/string?", ["lambda", ["x"], ["string/concat", "x", "!"]]],
    ["lambda", ["x"], "x"]]
  ```

  With `"value"` bound to `42` (a number), the first branch matches — returns `43`.
  With `"value"` bound to `"hi"` (a string), the second branch matches — returns `"hi!"`.
  Anything else falls through to the identity fallback.

  ### Structural predicates

  A predicate can also be a plain object whose keys must exist on the matched value and whose leaf values are predicates applied to the corresponding fields:

  ```json theme={null}
  ["match",
    { "type": "user", "profile": { "name": "Ada" } },
    [
      {
        "type": ["func/partial", "string/equals?", "user"],
        "profile": { "name": "value/string?" }
      },
      "value/identity"
    ],
    ["lambda", ["x"], null]]
  ```

  The structural predicate checks that:

  * the value has a `"type"` field that equals `"user"` (using `func/partial` to apply `string/equals?`)
  * the value has a `"profile"` object with a `"name"` field that is a string

  When the input object satisfies all field predicates, `"value/identity"` is called with the whole value and it is returned unchanged.

  <Note>
    Structural predicates are evaluated recursively. A field value can itself be a structural predicate object, enabling deep pattern matching on nested data shapes without writing a ladder of `cond` expressions.
  </Note>
</Accordion>
