Comptime covers compile-time computation: reflection, type manipulation, and const blocks.
const counter: mut = 0;
counter += 1; // valid at compile time
// counter += input().nextI32(); // COMPILE ERROR: frozen at runtime
const BlocksA const { ... } block executes its contents at compile time. Every value inside must be computable at compile time — if anything depends on runtime input, the compiler reports an error.
const fn functions resolve entirely at compile time and must be called inside a const block or assigned to a const binding; they cannot be called at runtime.
const result {
let x = 10;
let y = 20;
x + y // evaluated at compile time
};
import assets/data.json as Data;
const fn processJson(data: []char): JsonValue { ... }
const parsed = processJson(Data); // runs at compile time
Some macros and functions are overloaded to run at compile time; a compile-time
throwhalts compilation and displays the error message — equivalent tostatic_assertin other languages.
Use @ intrinsics to inspect types at compile time:
// Iterate the fields of a struct
for ( field in @fields MyStruct ) {
@println("{}: {}", field.name, field.type);
}
// Check a type's kind
let isPrim = (T is @primitive); // bool, i32, f64, etc.
let isStr = (T is @struct); // struct
let isComp = (T is @component); // component
let isUn = (T is @union); // union
let isEn = (T is @enum); // enum
// Inspect field visibility
for ( field in @fields MyStruct ) {
@println("{}: {}", field.name, field.visibility); // pub, mod, private
}
// Check nullability
let nullable = (T is @nullable); // ?T
This section is relevant for tooling authors and compiler contributors.
You can create a type and modify it before it is "finalized":
// Create a new type
type Custom = @struct;
// Add fields -- allowed while the type is not yet returned or instantiated
@appendField Custom, x: i32;
@appendField Custom, y: f32;
// Remove a field
@removeField Custom, x;
// Add methods
@appendMethod Custom, fn distance(self): f32 { sqrt(self.x*self.x + self.y*self.y) }
// The type is "done" once it's returned or instantiated
let p: Custom = Custom { x: 1, y: 2.0 };
// Primitive aliases are IMMUTABLE -- they have no fields to modify
type Celsius = i32;
@appendField Celsius, x: i32; // COMPILE ERROR: type is 'done' (primitive)
A type built via
@structis "done" the moment it is returned or instantiated. Until then,@appendField,@removeField, and@appendMethodare available. Passing the type to a generic function also counts as "done." A type created withtype(e.g.type Celsius = i32) is a primitive alias — it has no fields to modify and is always immutable. You can still add methods viaimplement, but you cannot@appendFieldor@removeField.
Zith Language Specification — Draft v0.9