ROX Language

ROX is a minimal, clarity-first programming language built on a simple belief:

Programming logic should not have to fight the language.

ROX removes implicit behavior, hidden conversions, and syntactic tricks so that expressing logic feels direct and mechanical rather than negotiated.

First Principles

Language Guarantees (v0)

Namespacing (v0)

ROX automatically namespaces all user-defined identifiers to prevent collisions with C++ keywords and standard library symbols.

Rule: You cannot define identifiers starting with roxv26_. Attempting to do so will result in a compilation error.

Example: Two Sum

function two_sum(list[int64] int64s, int64 target) -> list[int64] {
    int64 n = int64s.size();

    for i in range(0, n, 1) {
        for j in range(i + 1, n, 1) {

            rox_result[int64] r1 = int64s.at(i);
            if (isOk(r1)) {
                int64 v1 = getValue(r1);

                rox_result[int64] r2 = int64s.at(j);
                if (isOk(r2)) {
                    int64 v2 = getValue(r2);

                    if (v1 + v2 == target) {
                        return [i, j];
                    }
                }
            }
        }
    }

    return [-1, -1];
}

Notable Properties

Language Features (v0)

Operators

Types

Control Flow

Note: ROX intentionally has no while loop. Every loop must have an explicit upper bound — either via range(start, upperBound, step) or by iterating a finite collection. This guarantees all loops terminate.

Built-in Functions

Built-in Constants

Comments

ROX supports single-line comments starting with //.

// This is a comment
int64 x = 10; // This is also a comment

Math Library

int64

float64

Constants

Error Model

ROX does not use exceptions. Errors are explicit values:

rox_result[int64] r = int64s.at(i);
if (isOk(r)) {
    int64 value = getValue(r);
} else {
    print("Error: ", getError(r), "\n");
    return [-1, -1];
}

Nothing throws. Nothing hides.

User-Defined Types (Records)

Define types with named, typed fields. All fields are required at construction.

type User {
    id: int64
    name: string
}

function main() -> none {
    User u = User{ id: 7, name: "Taman" };
    print(u.name, "\n");

    User empty = default(User);  // zero constructor
    print(empty.id, "\n");       // 0
}

Records support field access (u.name), field mutation (u.name = "Apon"), copy semantics, nested composition, and functions as parameters/return values.

Compile-time checks: missing fields, unknown fields, duplicate fields, type mismatches, and uninitialized declarations are all caught at compile time.

Download & Build

You can verify and run algorithms locally using the Playground or by building the compiler from source.