Skip to main content
Kairo splits failure into two categories: expected failures you can predict and encode in your API, and faults that mean something has gone catastrophically wrong. They use different mechanisms, and that’s on purpose.

Expected failures

Modeled as Result<T, E> values. Part of the function’s signature. Callers handle them.

Faults

Terminate the current execution boundary. Not wrapped in Result. Not caught in v0.1.

Result<T, E>

Result<T, E> represents an outcome that is either a success carrying a T, or an expected failure carrying an E. It is part of the Kairo Core prelude, so it needs no import.
Rules:
  • The failure type E must be value-like.
  • Return either Result.success(...) or Result.failure(...).
  • The surrounding context must supply the expected Result<T, E> type in v0.1.

Inspecting a Result

Kairo v0.1 doesn’t have destructuring match patterns yet, so you inspect a Result through properties: Always branch first, then read the payload:
Reading result.value on a failure or result.error on a success is a runtime fault. Branch before you read.

Faults

A fault is an unexpected condition that stops execution. There is no user-facing fault-catching syntax in v0.1.
A fault at the application root terminates the process with a Pulse-generated non-zero exit code. Pulse may emit a diagnostic to stderr.
What produces a fault today:
  • Reading the wrong side of a Result (.value on failure or .error on success).
  • Contract violations at the Kairo runtime boundary.
  • Any condition Pulse categorizes as an unrecoverable execution failure.
What does not produce a fault:
  • Business rule violations (use Result.failure).
  • Missing optional data (use nullable types like Customer?).
  • Failed lookups (return T? or Result<T, E>).

Guidelines

Use T? when the answer is simply “there or not there” and the caller doesn’t care why. Use Result<T, E> when the failure carries meaning the caller might want to inspect, log, or branch on.
No. Kairo has no throw, no panic, and no try/catch. Expected failures return Result. Unexpected failures become faults, which are handled at the runtime boundary. Do not simulate exceptions.
No. E must be value-like. Failure payloads are facts you pass around, not identity-bearing participants.

Application entrypoint and Result

An application entrypoint can return Result<Int32, E>. Pulse treats a success payload as the process exit code, and a failure as a Pulse-generated non-zero application-failure exit.
Result.success(17) is a successful result state that still exits with code 17. Result.failure(...) is a distinct application-failure outcome.

Deferred features

  • Fault catching and recovery syntax.
  • Destructuring match patterns for Result.
  • Custom equality for Result payloads.

Next steps

Control flow

match, if, and pattern support today.

Pulse runtime

Exit codes and how faults terminate a process.