Type system
Kyna checks whether a value fits the type required by a binding, parameter, or return annotation. The compiler keeps parser annotations as TypeRef values and resolves them when checking the program.
Type compatibility
Compatibility is directional: a value may fit a broader type without the broader type fitting the original one.
intandfloatvalues fitnum.- A value fits a union when it fits at least one member of that union.
nullfits a nullable type.- An explicit
anyannotation bypasses static compatibility checks at that location. Inferred, unrelated types do not automatically becomeany.
The analyzer represents types with kyna::types::Type. Primitive types use shared instances in the type universe; function signatures, named types, unions, and nullable types form the rest of the graph.
Collections and other type shapes
The semantic type module can represent fixed arrays, dynamic slices, maps, pointers, structs, structural interfaces, tuples, directional channels, constrained type parameters, and aliases.
These internal representations do not mean that every shape is available in the current source grammar or runtime. Kyna's existing array<T> spelling has slice semantics. Array literals preserve their element type when you access an element by index.
Mutable and constant bindings
Binding mutability is separate from a value's type. The analyzer records whether a binding uses var or const and rejects assignment to a constant. Runtime cells repeat this check.
Object members have their own mutability. An immutable object reference can still expose a mutable field.
Function contracts
The analyzer checks parameter types and explicit return annotations. When a function has no return annotation, its result type is currently inferred dynamically at call sites. Explicit return contracts remain strict.
void and null are distinct types.
Interfaces
Interfaces (intf) are structural contracts checked at implements conformance and object-literal assignment:
intf Shape {
area(): float;
}
intf Named<T> extends Shape {
name: str;
label?: str;
(): int; // call signature
[key: str]: int; // index signature
}
class Circle implements Named<float> {
public name: str;
public fn area(): float { return 3.14; }
public fn _(): int { return 1; }
}extendsmerges parent contracts (a base's members are inherited); a generic parent can be specialized, e.g.extends Base<int>binds the parent's type parameter.- Generic interface parameters (
intf Named<T>) are instantiated atimplements/extendssites, with type substitution applied to inherited fields, methods, call signatures, and index signatures. - Optional properties (
name?: T) are not required of implementing classes or object literals. implementsrequires compatible public fields and methods; method parameter and return types are checked after generic substitution.
Type-definition files (.kyna.d, .d.ky, .ky.d) are ambient: they declare interfaces used only at compile time and never execute.
Source captured: 2026-10-11