The object model, type system, dispatch, generics, and numerics.
Core-0 Objects, Types, and Messages
Status: normative
Objects and visibility
C0-OBJ-001 — Object forms. Every runtime value participates in the message
model. A value is sealed, inline/value-semantic, and statically dispatched. A
class is a stable heap object whose bare type is its unique owning handle.
C0-OBJ-002 — Explicit openness. Classes and class messages are sealed by
default. open permits one concrete base chain and override dispatch. An
override must say override, preserves its inherited dispatch contract, and is
sealed again unless it also says open.
C0-OBJ-003 — Explicit visibility. Every declaration and member writes one
of public, module, or private. Fields are accessed explicitly through a
receiver; there are no implicit properties, protected visibility, hidden
friend access, or lookup-based visibility exceptions.
Types and evaluation
C0-TYPE-001 — Nominal equality. User values, classes, enums, and errors are nominal. Generic constructors are invariant. The explicit projection from a derived class handle or borrow to its base is the only Core-0 subtype relation.
C0-TYPE-002 — No implicit conversion. Core-0 has no null, truthiness, numeric widening, structural record conversion, user-defined conversion, or ambient coercion. Permitted contextual operations are literal fitting, bounded reborrowing, class-base projection, and checked generic substitution.
C0-TYPE-003 — Core types. The compiler supplies the scalar, Never,
Unit, Text, Bytes, Option, Result, InitError, collection, ownership,
allocator, class-descriptor, and root-object types enumerated by the semantic
reference. Index is target-sized and forbidden in a portable public .zli
signature.
C0-TYPE-004 — Evaluation order. Operands and arguments evaluate left to
right. && and || short-circuit. Assignment produces a replacement before
dropping and storing over the old initialized place; failed production leaves
the old place initialized.
C0-TYPE-005 — Closed variants. Enums and errors are closed nominal
variants. match is exhaustive, rejects duplicate or unreachable arms, and
preserves ownership of observed borrows while consuming selected payloads from
owned non-Copy scrutinees.
C0-TYPE-006 — Explicit variant construction. A closed enum or error value
is constructed as Type.Variant(arguments...), where Type resolves to the
nominal enum/error descriptor and Variant resolves to exactly one declared
variant. Arguments correspond positionally and exactly to the variant payload;
a fieldless variant is written with an explicit empty (). This form is a
statically checked construction operation rather than an ordinary message
lookup, evaluates payload arguments left to right, and performs no allocation
or implicit conversion.
C0-TYPE-007 — Structural Copy for closed carriers. A closed enum or error
instance is Copy if and only if every payload of every variant is Copy; a
fieldless declaration is therefore Copy. The compiler-provided Option,
Result, and InitError carriers use the same structural rule over all of
their payload type arguments. Matching a named owned non-Copy carrier requires
move(name), while a fresh temporary transfers directly. An owned arm binding
copies a Copy payload and moves a non-Copy payload. When matching Ref<C> or
Mut<C>, a Copy payload is copied and a non-Copy payload binds as an
arm-scoped Ref<T>; matching never creates an implicit Mut<T>.
C0-TYPE-008 — Finite inline variant layout. Every closed variant instance
has a finite, statically known inline layout. A cycle containing only inline
owned-payload edges is invalid; recursive data must break each such cycle with
an explicit indirection such as a class handle, Box, or Shared. Layout,
payload-count, and size calculations use checked arithmetic and must fail with
a diagnostic when they exceed the portable implementation bounds.
The bounded Stage0 sealed-value profile for ZLM1 schema 1.8 admits one nominal,
sealed, nongeneric value declaration with exactly one public let field. The
field has one exact scalar type of at most 32 bits from the set fixed by
C0-ART-003. The value declares exactly one public initializer, which must
return exactly Result<Self, E> with an empty or explicitly declared effect
set and with E inside the bounded Result payload set.
The expression Self { field: value } is valid only inside the declaring value initializer. It names the sole field exactly once, type-checks its expression
against the exact declared scalar, and produces a fresh temporary only after
the field is initialized. Self cannot otherwise escape the initializer. A
missing, repeated, differently named, or differently typed field is rejected.
The user value remains non-Copy; a named owner requires move, while a fresh
constructed temporary transfers directly.
This is an implementation restriction, not structural record compatibility. Other Core-0 value shapes remain reserved for a later schema/profile. Stage0 must reject a value outside this boundary before checked-module emission and cannot reinterpret it as a scalar alias, class, enum, backend struct, or fieldless value.
The schema-1.9 selfhost byte-kernel profile is the next specified restriction,
but is not yet emitted. It admits multiple declarations and multiple fields,
including private mutable implementation fields, only under the exact
zerglang.selfhost-intrinsics/1 catalog. Field order is source order and every
field retains an exact type-instance identity and independent move path. This
is nominal aggregate semantics, never structural record compatibility or a
host C layout.
For that profile, Unit.value() produces the sole zero-size Unit value and
Never is uninhabited. Unit and Never are Copy; Never never occupies a
place or payload. Catalog selectors admit receiver kinds Ref, Mut, owned Self, and Class<Self> with the exact ownership stated by their signatures.
A type receiver on a catalog construction selector may name a value
descriptor; it does not imply class allocation or runtime dispatch.
Result<T, E>, Array<Byte>, Slice<Byte>, Ref<T>, Mut<T>, and
Allocator<BytesError> are compiler-known concrete type instances for this
profile. Their canonical instance records are fixed by schema 1.9. This
admission does not admit user-defined generics, source specialization, generic
inference, or arbitrary Array<T>/Slice<T> instances in the first byte
kernel.
Messages and generics
C0-MSG-001 — Explicit domain and receiver. Every executable message says
algorithm and declares self: Ref<Self>, self: Mut<Self>, self: Self, or
type: Class<Self> as its receiver. There are no free functions or implicit
receivers.
C0-MSG-002 — Singular lookup. A send resolves from the statically known receiver and one selector. Core-0 has no overload search, argument-dependent lookup, extension search, or alternate named spelling for an operator.
C0-MSG-003 — Dispatch identity. A named selector includes its name and non-receiver parameter labels. An operator selector includes token and arity. Receiver ownership, domain, parameters, result, closed error carrier, generic requirements, effects, and contracts form the dispatch contract.
C0-MSG-004 — Override compatibility. An override preserves the dispatch contract, may narrow its effect set, cannot strengthen caller preconditions, and cannot weaken inherited postconditions.
C0-GEN-001 — Structural requirements. Compile-time polymorphism uses generic parameters constrained by required message signatures. It does not introduce a nominal interface/protocol hierarchy or arbitrary compile-time evaluation.
C0-GEN-002 — Checked specialization. Each concrete generic instance has a canonical identity including declaration, substitutions, requirements, numeric preset, and edition. Required messages are resolved before typed IR is emitted; failure produces a requirement tree in diagnostics.
Numeric semantics
C0-NUM-001 — Independent preset. Every checked package selects exactly one
of exact, modular, or approximate. The preset is independent of
verification and materialization modes and is recorded at every artifact and
call boundary where compatibility matters.
C0-NUM-002 — Integer safety. exact traps on overflow, underflow, invalid
shift, division by zero, and signed-minimum divided by negative one. modular
wraps addition, subtraction, multiplication, and negation at the declared
width, but retains the exceptional division and shift faults.
C0-NUM-003 — Approximation boundary. approximate never relaxes type,
memory, bounds, ownership, or integer safety. Floating reassociation,
contraction, vectorization, or approximation is legal only when a reflected
error/tolerance contract grants that freedom.