Reference

Primitives

Language and type primitives for values, memory views, ownership, layout, and absence.

Scalar Values

PrimitivePurposeCurrent status
BoolConditions and logical results. Only Bool is accepted in if and while conditions.Runnable
i8 i16 i32 i64Signed fixed-width integers.Runnable
u8 u16 u32 u64Unsigned fixed-width integers.Runnable
usize isizePointer-sized integers.Runnable
f32 f64Floating-point values.Runnable
charByte-sized character value for ASCII/parser/codec-style work.Runnable
StringText value used by string literals and current I/O examples.Runnable
VoidReturn type for functions that produce no useful value.Runnable

Integer literals support decimal, hexadecimal, binary, octal, _ separators, and optional suffixes such as _u8 or _usize.

let count: u32 = 0x12c_u32let byte: u8 = 255let page: usize = 4_096

Primitive numeric types do not implicitly narrow, widen, or change signedness. Use an explicit cast when the conversion is intentional.

let count: u32 = 300let byte: u8 = count as u8let whole: i32 = 7.9 as i32let marker: u8 = 'A' as u8

Absence And Fallibility

Maybe<T> represents an optional value. null is accepted only when the expected type is known to be Maybe<T>.

let name: Maybe<String> = nulllet fallback = name else "world"

Fallible functions are marked with raises, and check propagates the current error. raises is part of a function signature rather than a runtime exception mechanism.

The native compiler accepts explicit error sets for user-defined fallible functions.

fun validate(ok: Bool) -> i32 raises { InvalidInput } {    if ok == false {        raise InvalidInput    }    return 42} fun run() -> Void raises { InvalidInput } {    check validate(true)}

The native compiler lowers check on Maybe<T> to a direct branch for the first recoverable helper slice. A failed Maybe check returns the function's default failure value without exceptions or unwinding.

User-defined error flow lowers to small status/result structs only when a function actually raises named errors.

Memory And Ownership

Zero makes memory shape visible in types. These forms are primitive type constructors because they affect ownership, borrowing, layout, and cleanup.

PrimitivePurpose
[N]TFixed-size array with N elements of T.
Span<T>Non-owning pointer plus length.
ref<T>Non-owning shared reference.
mutref<T>Non-owning mutable reference.
owned<T>Move-only value that owns cleanup responsibility.
const TRead-only view of T.
shape BufferView {    bytes: Span<u8>,    owner: Maybe<mutref<Alloc>>,} pub fun len(view: BufferView) -> usize {    return std.mem.len(view.bytes)}

Alloc is a capability type used by allocation APIs. Heap allocation should be visible in function parameters and documentation; there is no hidden global allocator.

Allocator primitives are explicit handles:

PrimitiveBehavior
NullAllocAlways reports allocation failure, useful for proving a path does not allocate.
FixedBufAllocAllocates from caller-owned mutable bytes and returns borrowed MutSpan<u8> views.
std.mem.arena(buffer)Arena-style fixed-buffer allocation over caller storage.
PageAlloc, GeneralAllocExplicit handles, not ambient global heaps.
std.mem.byteBuf(alloc, len)Returns Maybe<owned<ByteBuf>> backed by explicit caller storage.

Borrow expressions create references without allocation or runtime metadata. Use &value for ref<T> and &mut value for mutref<T>.

fun read_x(point: ref<Point>) -> i32 {    return point.x} fun write_x(point: mutref<Point>, value: i32) -> Void {    point.x = value} let shared = &pointwrite_x(&mut point, 5)

An owned<T> local is automatically cleaned up at lexical scope exit when T defines the canonical non-raising method fun drop(self: mutref<Self>) -> Void.

Cleanup is lowered to a direct call and skipped once the owned binding has moved.

shape Temp {    bytes: MutSpan<u8>,     fun drop(self: mutref<Self>) -> Void {        self.bytes[0] = 0    }}

Layout Primitives

User-defined types are not primitives, but some layout markers are primitive because they define how values cross ABI or binary boundaries.

FormPurpose
shapeDefault Zero aggregate layout. Not ABI-stable by default.
extern shapeC ABI-compatible aggregate layout for the selected target.
packed shapeBit-exact layout with declared field widths.
enum Name : uNEnum with an explicit integer backing type.
choiceTagged choice value. Exhaustive matching is required.
extern shape CPoint {    x: i32,    y: i32,} enum Color : u8 {    red,    green,    blue,}

Capability Names Are Not Primitives

Names such as World, Fs, Net, Env, Args, Clock, Rand, and Proc are capability surfaces.

They are foundational to Zero's effect model, but they are not primitive values in the same sense as Bool, u32, Maybe<T>, or Span<T>.

pub fun main(world: World) -> Void raises {    check world.out.write("hello\n")}

Current Native Status

The native compiler currently supports:

  • checked primitive integer widths and exact C integer types
  • explicit casts among primitive integers, floats, and byte char
  • memory-oriented generic forms
  • Maybe<T> and native layouts for span views
  • source-level ref<T> and mutref<T> borrows
  • lexical moves for owned<T>
  • direct drop cleanup calls for live owned locals
  • compiler-known owned<File> cleanup
  • allocation through NullAlloc, mutable FixedBufAlloc, and ByteBuf

None of these ownership features add runtime ownership machinery.

Not part of the current native status:

  • f16
  • Unicode scalar character handling
  • fuller borrow and alias analysis
  • Arena and general allocator behavior
  • drop glue for generic containers
  • more exhaustive layout conformance across target ABIs