value (compared by its content) and an object (compared by its identity) is not just technical — it encodes how a concept behaves in the real world. A Money amount with the same number is the same amount regardless of which instance you hold; a Customer with the same name is still a different person. Kairo makes this distinction explicit, and all other type-system choices — non-null by default, no implicit conversions, no type aliases — serve the same goal of keeping domain intent clear and unambiguous.
Scalar Types
Kairo provides six built-in scalar types. There are no automatic widening conversions between them.Decimal is the default type inferred for fractional literals like 19.99. If you need Float64, you must annotate the binding explicitly. This keeps financial and domain-numeric logic free from floating-point surprises.Temporal Types
Kairo includes first-class temporal types for dates, times, and durations. These are part of the Core prelude and require no import.Collection Types
Kairo’s built-in collections come in immutable and mutable variants. Immutable collections are the default — they cannot be modified after construction.Immutable Collections
Mutable Collections
Nullability
All types in Kairo are non-null by default. A value can only benull if its type is explicitly marked nullable with a trailing ?.
T? as if it were a T.
value Declarations
A value is an immutable, content-based domain type. Two value instances with identical field contents are considered equal — there is no notion of reference identity. Use value for domain concepts that are defined by what they contain: money amounts, identifiers, addresses, measurements.
value are always immutable. You cannot mark a member var inside a value. All stored members must themselves be value-like — you cannot embed an object-typed member inside a value.
object Declarations
An object is an identity-bearing, stateful type. Two object instances are distinct even if all their fields are identical — identity is intrinsic. Use object for domain concepts that change over time and have a lifecycle: customers, orders, sessions, services.
var. Immutable members (no var) can only be set in init. Each object has exactly one init in v0.1.
contract Declarations
A contract declares a capability promise — a named set of requirements that any conforming type must satisfy. Contracts play the role that interfaces play in other languages.
In v0.1, only
value and object types can declare contract conformance. Conformance must be declared at the type definition site — there are no retroactive or extension conformances in this version.enum Declarations
An enum defines a closed set of named cases. Use enum when a concept has a fixed, known set of states or categories.
Generics and Constraints
Kairo supports generic type parameters using angle-bracket syntax. Constrain a type parameter by naming a contract it must satisfy:T: Named means the type argument must conform to the Named contract.
Result<T, E> — Outcome Type
Result<T, E> is the standard way to represent an operation that can either succeed with a value of type T or fail with an error of type E. It is part of the Core prelude and available without import.
Result using .isSuccess, .isFailure, .value, and .error:
Result, faults, and error-type design.