Types
Zeus is a statically typed language. Every variable, parameter, and return value has a type known at compile time. For local variables, the type is usually inferred from the initializer — you only need to write it explicitly when it matters.
Primitive Types
Integer Types
Zeus provides signed and unsigned integers of various sizes:
| Type | Size | Range |
|---|---|---|
i8 | 8-bit | -128 to 127 |
i16 | 16-bit | -32,768 to 32,767 |
i32 | 32-bit | -2.1B to 2.1B |
i64 | 64-bit | -9.2×10¹⁸ to 9.2×10¹⁸ |
u8 | 8-bit | 0 to 255 |
u16 | 16-bit | 0 to 65,535 |
u32 | 32-bit | 0 to 4.2B |
u64 | 64-bit | 0 to 1.8×10¹⁹ |
let small = 127; // inferred: i32 (integer literals default to signed, ≥ i32)let normal = 1000000; // inferred: i32let big: i64 = 9223372036854775807; // explicit: value requires i64let positive: u32 = 4000000000; // explicit: the literal fits u32, so it adopts u32Floating-Point Types
| Type | Size | Precision |
|---|---|---|
f32 | 32-bit | ~7 decimal digits |
f64 | 64-bit | ~15 decimal digits |
let pi = 3.14159; // inferred: f64let precise: f32 = 3.14159; // explicit: want f32 precisionBoolean Type
The boolean type has two values: true and false.
let isReady = true;let hasError = false;Void Type
void indicates a function returns no value. The annotation is optional — omitting the return type is equivalent to writing : void:
function logMessage() { // No return statement needed}
// Explicit : void means the same thingfunction reset(): void { // ...}Null
null represents the absence of a value for object types:
let p: Point = null;Numeric Literals
Integer Literals
Zeus supports multiple number bases:
let decimal = 42;let binary = 0b101010; // 42 in binarylet octal = 0o52; // 42 in octallet hex = 0x2A; // 42 in hexadecimalUse underscores for readability:
let million = 1_000_000;let mask = 0b1111_0000;Floating-Point Literals
let simple = 3.14;let scientific = 6.022e23; // Scientific notationType Compatibility
Implicit Conversions
Zeus performs automatic widening conversions:
let small: i8 = 10;let big: i32 = small; // OK: i8 → i32
let integer = 42;let floating: f64 = integer; // OK: i32 → f64Allowed implicit conversions:
- Smaller integers → larger integers (e.g.,
i8→i32) - Integers → floats (e.g.,
i32→f64) - An integer literal → any integer type whose range holds its value (e.g.
let b: u8 = 200) null→ any object typestring↔u8[](creates a copy)- A derived object → a base type (upcast, e.g.
Dog→Animal)
Type Errors
Narrowing a runtime value is not implicit — use as:
let big: i32 = 1000;let small: i8 = big; // Error: use `big as i8`let f: i32 = 2.0; // Error: floats never implicitly become ints — use `2` or `2.0 as i32`Incompatible types cause errors:
let num: i32 = 42;let flag: boolean = num; // Error: cannot convert i32 to booleanType Casting with as
When an implicit conversion isn’t allowed, as performs an explicit cast: value as Type.
Numeric and boolean casts
Numeric casts are unchecked and cost nothing at runtime — they truncate or wrap, exactly like
Rust’s as, Go, or C. Float→int truncates toward zero.
let big: i32 = 300;let small: u8 = big as u8; // 300 wraps to 44 (300 mod 256)
let pi: f64 = 3.9;let n: i32 = pi as i32; // 3 (truncates toward zero)
let flag: i32 = true as i32; // 1let on: boolean = 5 as boolean; // true (any non-zero → true)Casting between unrelated types (e.g. "hi" as i32) is a compile-time error.
Object downcasts
as also narrows an object reference to a subclass. This is checked at runtime: if the object
isn’t actually an instance of the target class, it throws a ClassCastException. Casting between
classes in unrelated hierarchies is a compile-time error.
class Animal { public legs: i32; constructor(l: i32) { this.legs = l; } }class Dog extends Animal { public name: string; constructor() { super(4); this.name = "Rex"; }}
let a: Animal = new Dog(); // implicit upcastlet d: Dog = a as Dog; // downcast — runtime-checked, succeeds hereconsole.log(d.name); // "Rex"
let other: Animal = new Animal(2);let bad: Dog = other as Dog; // throws ClassCastException (not a Dog)Upcasts (a derived object → a base type) need no as and no runtime check — they happen
implicitly.
Complex Types
Strings
The string type represents immutable UTF-8 text:
let greeting = "Hello, World!";let emoji = "Zeus 🚀";Strings can be implicitly converted to u8[] (mutable byte array) and vice versa:
let text: string = "Hello";let bytes: u8[] = text; // Creates mutable copybytes[0] = 'h'; // Modify the copylet modified: string = bytes; // Back to stringSee Strings for more details.
Arrays
Arrays are declared with Type[] syntax:
let numbers: i32[] = new i32[];let matrix: f64[][] = new f64[][]; // 2D arraySee Arrays for more details.
Classes
Classes define custom object types:
class Rectangle { public width: f64; public height: f64;}
let rect: Rectangle = new Rectangle();See Classes for more details.
Function Types
Functions can be stored in variables:
function add(a: i32, b: i32): i32 { return a + b;}
let operation: function(i32, i32): i32 = add;Type Checking
Zeus performs thorough type checking at compile time:
function process(value: i32): boolean { return value > 0;}
let result = process(42); // inferred: boolean
// let wrong: i32 = process(42); // Error: boolean not assignable to i32// process("hello"); // Error: string not assignable to i32