Zenth is strongly typed with type inference for local variables. Function signatures always require explicit types.

#Integer Types

Zenth has a single integer type: Int (64-bit signed).

let x = 42;          // Int (inferred)
let big: Int = 999;

Integer literals can use underscores for readability:

let million = 1_000_000;

#Built-in Integer Constants

Zenth provides built-in constants for the integer range limits:

ConstantValueDescription
INT_MAX9223372036854775807Maximum Int value (2^63-1)
INT_MIN-9223372036854775808Minimum Int value (-2^63)

These are true constants and cannot be reassigned:

let big = INT_MAX;
let small = INT_MIN;

// Use in expressions
if score < INT_MAX {
    Println("not at the limit yet");
}

#Base Conversion

Use .to_base(base) to convert an integer to a string in a given base (2-36):

let hex = 255.to_base(16);   // "ff"
let bin = 10.to_base(2);     // "1010"
let oct = 63.to_base(8);     // "77"

#Floating-Point Types

TypeSizeDescription
Float64-bitFloating-point type (default for float literals)
let pi = 3.14159;         // Float (inferred)
let ratio: Float = 0.75;

Zenth has a single floating-point type: Float. Legacy names like f32 and f64 are not valid.

let a: Float = 1.5;
let b = Float("2.25");
let parts = ["3.5", "4.5"];
let nums = parts.to_float();

#Boolean

let active = true;
let done = false;

Booleans are used in if conditions and logical expressions.

#String

The Str type holds text:

let greeting = "Hello, World!";

See Strings for interpolation and raw string details.

#Byte

The Byte type represents a single byte:

let b: Byte = 65;

Indexing into a string returns a one-character Str.

#Date

The Date type represents a calendar date. Create dates with Date.today() or Date.from():

let today = Date.today();
let epoch = Date.from("1970-01-01");
let custom = Date.from("01/13/2007", "%m/%d/%Y");

Date methods:

  • .format(fmt) — format as string (%Y-%m-%d, %B %d, %Y, etc.)
  • .add(val) / .add(val, unit) — add days, months, or years (returns new Date)
  • .sub(val) / .sub(val, unit) — subtract days, months, or years (returns new Date)

See Dates for full documentation.

#Nil

nil represents the absence of a value for reference types (hashmaps, arrays, objects). It must be used with an explicit type annotation:

var m: Hashmap(Str, Int) = nil;
var items: Array(Int) = nil;

Primitive types (Int, Str, Bool, Float) cannot be nil.

#Composite Types

#Range Objects

Range(start, end) and Rangei(start, end) return a range object — a lightweight value type that is iterable and supports O(1) containment checks.

let r  = Range(0, 10);    // exclusive: [0, 9]
let ri = Rangei(0, 10);   // inclusive: [0, 10]
let rs = Range(0, 20, 3); // with step: [0, 3, 6, 9, 12, 15, 18]

Methods:

MethodReturnsDescription
.contains(x)BoolO(1) bounds check: is x within the range?

Built-ins that work on range objects:

Built-inDescription
Len(r)Number of elements in the Range (O(1))

Iteration:

Range objects are iterable in for-in loops:

for i in Range(0, 5) {
    Println(i);   // 0 1 2 3 4
}

for i, v in Rangei(10, 13) {
    Println("{i}: {v}");
}
// 0: 10
// 1: 11
// 2: 12
// 3: 13

Containment checks:

let r = Range(1, 10);
Println(r.contains(5));   // true
Println(r.contains(10));  // false (exclusive end)

let ri = Rangei(1, 10);
Println(ri.contains(10)); // true (inclusive end)

Note: .contains() is a bounds check, not a sequence membership test. For Range(0, 10, 3) (sequence [0, 3, 6, 9]), .contains(5) returns true because 5 is within the bounds [0, 10).

#Arrays

Dynamic arrays use Array(Type) syntax:

let numbers: Array(Int) = [1, 2, 3, 4, 5];

See Arrays for more details.

#Hashmaps

Hashmaps are key/value collections. Create an empty hashmap with Hashmap(KeyType, ValueType):

obj Point {
    x: Int;
    y: Int;
}

var grid = Hashmap(Point, Str);
let pt = Point(x=1, y=2);
grid[pt] = "#";

For object keys, hashmap lookup is value-based: another Point(x=1, y=2) resolves the same entry.

#Sets

Sets are unordered collections of unique values. Create an empty set with Set(Type):

var visited = Set(Str);
visited.add("start");
visited.add("middle");
visited.exists("start");  // true
visited.remove("middle");
Println(Len(visited));       // 1

Sets support Int, Str, Bool, and other comparable types as elements.

You can also convert an array into a set with Set(arrayExpr). Duplicate elements are removed:

let letters = ["a", "b", "a"];
let unique = Set(letters);
Println(Len(unique));  // 2

#Sets of Tuples

Sets can hold tuples, enabling composite keys without string round-tripping:

var dots = Set(Tuple(Int, Int));
dots.add(Tuple(6, 10));
dots.add(Tuple(0, 14));
dots.add(Tuple(6, 10));  // duplicate, ignored
Println(Len(dots));       // 2

if dots.exists(Tuple(6, 10)) {
    Println("found");
}

for dot in dots {
    Println("{dot.0},{dot.1}");
}

Tuple elements must be comparable types (scalars, strings, booleans). Tuples containing arrays or maps cannot be used as set elements.

#Tuples

Tuples are fixed-size ordered values that can hold mixed types. They support both positional and named fields:

let t = Tuple("a", 1);
Println(t.0);      // positional access

let person = Tuple(name="Alice", age=30);
Println(person.name);  // named access

See Tuples for named tuples, destructuring, and usage in functions.

#Objects

User-defined types with named fields:

obj Point {
    x: Float;
    y: Float;
}

let p = Point(x=1.0, y=2.0);

See Objects for methods and self.

#Function Types

Function types describe the signature of a function value. Use them in parameter lists, variable declarations, and type aliases:

Fn(Int) -> Int           // takes Int, returns Int
Fn(Str, Int) -> Bool     // takes Str and Int, returns Bool
Fn(Int)                  // takes Int, returns nothing

See Functions for examples of higher-order functions and passing functions as values.

#Type Aliases

Type aliases let you give a reusable name to any type expression:

type Points = Array(Point);
type Point = Tuple(x: Int, y: Int);
type AdjList = Hashmap(Str, Array(Str));
type Predicate = Fn(Int) -> Bool;

Use the alias anywhere you would normally write the underlying type:

type Ints = Array(Int);
type Point = Tuple(x: Int, y: Int);

fn sum(nums: Ints) -> Int {
    var total = 0;
    for n in nums {
        total += n;
    }
    return total;
}

let values: Ints = [10, 20, 30];
let origin: Point = Tuple(x=0, y=0);

Println(sum(values));
Println("{origin.x}, {origin.y}");

Aliases do not create a new runtime type; they are shorthand for an existing type. The aliased type must still be a valid type expression.

#Enums

Enums define a type with a fixed set of named variants:

enum Direction {
    North;
    South;
    East;
    West;
}

let d = Direction.North;

See Enums for explicit values, comparison, and match usage.

#Type Conversions

Use the Str() built-in to convert any value to a string:

let n = 42;
let s = Str(n);    // "42"
Println(Str(3.14)); // "3.14"

Use Int() to convert strings or floats to integers. With two arguments, the second specifies the base:

let a = Int("42");         // 42
let b = Int(3.14);         // 3
let bin = Int("1010", 2);  // 10 (binary)
let hex = Int("ff", 16);   // 255 (hexadecimal)
let oct = Int("77", 8);    // 63 (octal)

This is equivalent to "ff".to_int(16) but reads more naturally as a conversion function.

#Operators

#Arithmetic

OperatorDescription
+Addition (also string concatenation)
-Subtraction
*Multiplication
/Division
%Modulo

#Comparison

OperatorDescription
==Equal
!=Not equal
<Less than
>Greater than
<=Less than or equal
>=Greater than or equal

#Logical

OperatorDescription
&&Logical AND
||Logical OR
!Logical NOT

#Bitwise

OperatorDescription
&Bitwise AND
|Bitwise OR

Bitwise operators require Int operands on both sides. They are useful for flag manipulation, masking, and low-level integer operations.

let a = 0b1100;   // 12
let b = 0b1010;   // 10

let and_result = a & b;   // 0b1000 = 8
let or_result  = a | b;   // 0b1110 = 14

Println(Str(and_result));  // 8
Println(Str(or_result));   // 14

Arithmetic operators require matching numeric types on both sides. The + operator also works for string concatenation when both sides are Str.