3Variables and Constants
Every variable declaration in Cryo has three parts: a mutability qualifier (const or mut), a name with an optional type annotation, and an optional initialiser. When the annotation is omitted, the binding's type is inferred from its initialiser.
const name: string = "Cryo"; // immutable binding
mut counter: int = 0; // mutable binding
counter = counter + 1; // reassignment requires `mut`
const greeting = "hello"; // inferred: string
mut total = 3 + 4; // inferred: i32
mut it = arr.iter(); // inferred: the concrete iterator type
Immutable by default. A const binding cannot be reassigned after initialisation. Mutability is opt-in via mut, which makes mutation visible at the declaration site.
mut y: int; // declared without an initialiser; assigned later
Globals. Module-level const declares an immutable global; module-level mut declares mutable global state. Use the latter sparingly. An initializer that is a constant expression is folded into the program: a number, a null or string literal, an array literal of those, and a struct literal writing every field with one of those; array and struct literals nest in each other. Any other - a call, another global's value - is computed once, before main runs, a module's globals after those of the modules it imports, in the order they are declared. A ![thread_local] global gets its folded initializer in every thread's copy, so its initializer must fold: one that would be computed would reach the main thread's copy only, and is refused (E0646).
const VERSION: string = "1.0.0";
mut g_counter: u64 = 0;
const LIMIT: i32 = Json::twice(3); // 6, computed before `main`
Local type inference. The type annotation may be omitted when an initialiser is present; the binding adopts the initialiser's concrete type (
const x = 10;infersi32,mut p = Point { ... };infersPoint). Because the inferred type is the concrete one the initialiser produces - not an erasedimplement Trait- methods on it stay callable, somut it = arr.iter(); it.take(3)...works without naming the iterator type. Inference is purely local: it reads only the initialiser of the same statement, never later uses. A binding with no initialiser therefore still needs an annotation (mut y: int;), and an initialiser that yields no value (void) cannot be inferred (both areE0104). There are still no implicit conversions and no flow- or program-level inference.
const NAME: Type = value;At module level, a true compile-time constant, conventionally SCREAMING_SNAKE_CASE. (mut at module level declares mutable global state instead.)
const name: stringprimitive stringNUL-terminated raw string (u8*), matching the C ABI. Length-typed text is Str / String.
mut name: Type = value;A mutable binding, reassignable after declaration - mutability is opt-in, const is the default. At module level it declares mutable global state. Before & it marks an exclusive reference or receiver instead.
mut counter: intmut counter: intconst greeting: stringmut totalmut itmut y: intconst VERSION: stringmut g_counter: u64const LIMIT: i32const name: Type = value;An immutable binding: it cannot be reassigned after initialisation. The annotation may be omitted when an initialiser is present - the binding takes the initialiser's concrete type, inferred locally. Mutability is opt-in through mut.
nullThe null pointer literal, valid in any pointer context - including the primitive string, which is a NUL-terminated u8*. Compare with == null; it is not an Option.
const xmut p: Pointfunction name(count: i32, args...)A variadic parameter: the trailing bucket receives any number of further arguments with C's calling convention, so the function stays ABI-compatible with the printf family. Wrap the bucket in VaArgs to read typed values from it.
implement struct Name { ... }
implement trait Trait for Type { ... }
implement u64 { ... }Adds methods to a type outside its declaration. implement struct T (or enum, or a bare primitive) opens an inherent block; implement trait Tr for T supplies a trait's methods for one type. Resolution is at compile time - no dynamic dispatch.