Syntax Basics
A comprehensive guide to the core language features of Reox.
Variables: Immutable vs Mutable
Reox is designed with safety in mind. Variables are immutable by default, meaning once assigned, they cannot be changed. Use let mut to create mutable variables.
// ═══════════════════════════════════════
// IMMUTABLE VARIABLES (Default)
// ═══════════════════════════════════════
let x: int = 42;
let name: string = "Reox";
let pi: float = 3.14159;
// x = 10; // ❌ ERROR: Cannot assign to immutable variable
// name = "New"; // ❌ ERROR: Variable is immutable
// ═══════════════════════════════════════
// MUTABLE VARIABLES (Explicit)
// ═══════════════════════════════════════
let mut counter: int = 0;
counter = 10; // ✓ OK - counter is mutable
counter += 5; // ✓ OK - compound assignment
counter++; // ✓ OK - increment
// Mutable collections
let mut items = [1, 2, 3];
items = push(items, 4); // [1, 2, 3, 4]
let mut config = map_new();
config = map_set(config, "debug", true);Why immutable by default? Immutability prevents accidental changes, makes code easier to reason about, and enables safe concurrent programming. Only mark variables as mut when you need to modify them.
Shadowing vs Mutation
You can "shadow" an immutable variable by re-declaring it with the same name:
let value = 10;
let value = value * 2; // Shadowing - creates new binding (20)
let value = to_string(value); // Can even change type
// vs Mutation (requires mut)
let mut count = 10;
count = count * 2; // Mutation - same binding, new valuePrimitive Types
Reox has statically typed primitives with type inference.
let count: int = 42; // Integer
let price: float = 19.99; // Float
let name: string = "NeolyxOS"; // String
let active: bool = true; // Boolean
let nothing = nil; // Nil (null)
// Type inference
let inferred = 100; // Inferred as int
let text = "Hello"; // Inferred as stringCompound Assignments & Operators
Shorthand operators for modifying mutable variables.
let mut x: int = 10;
// Arithmetic compound operators
x += 5; // x = x + 5 → 15
x -= 3; // x = x - 3 → 12
x *= 2; // x = x * 2 → 24
x /= 4; // x = x / 4 → 6
x %= 4; // x = x % 4 → 2
// Increment and Decrement
x++; // Post-increment: returns old value, then adds 1
++x; // Pre-increment: adds 1, then returns new value
x--; // Post-decrement
--x; // Pre-decrement
// Practical example in loop
let mut i = 0;
while i < 10 {
print(i++); // Prints 0-9
}Functions
Functions are declared with fn. Parameters have explicit types, and return types are specified after ->.
// ═══════════════════════════════════════
// BASIC FUNCTION
// ═══════════════════════════════════════
fn add(a: int, b: int) -> int {
return a + b;
}
// Function without return (void)
fn greet(name: string) {
print("Hello, " + name);
}
// ═══════════════════════════════════════
// CALLING FUNCTIONS
// ═══════════════════════════════════════
let result = add(10, 20); // 30
greet("Reox"); // Prints: Hello, ReoxInter-Function Calls & Composition
Functions can call other functions, enabling modular composition:
// Helper functions
fn square(n: int) -> int {
return n * n;
}
fn double(n: int) -> int {
return n * 2;
}
// Composed function using helpers
fn process(value: int) -> int {
let squared = square(value);
let doubled = double(squared);
return doubled;
}
// Chain calls inline
let result = double(square(5)); // 50
// ═══════════════════════════════════════
// RECURSIVE FUNCTIONS
// ═══════════════════════════════════════
fn factorial(n: int) -> int {
if n <= 1 {
return 1;
}
return n * factorial(n - 1);
}
fn fibonacci(n: int) -> int {
if n <= 1 { return n; }
return fibonacci(n - 1) + fibonacci(n - 2);
}Async Functions & Await
// Async function declaration
async fn fetch_data(url: string) -> string {
let response = await http_get(url);
return response;
}
// Multiple async calls
async fn load_user_data(id: int) {
let user = await fetch_user(id);
let posts = await fetch_posts(user.id);
print("Loaded " + len(posts) + " posts");
}Loops and Iteration
Reox supports while loops, for..in loops, range expressions, and loop control with break and continue.
While Loops
// Basic while loop
let mut count: int = 0;
while count < 5 {
print(count);
count++;
} // Prints: 0, 1, 2, 3, 4
// Infinite loop with break
let mut running = true;
while running {
let input = read_input();
if input == "quit" {
running = false;
}
}For Loops with Arrays
// Iterate over array elements
let fruits = ["apple", "banana", "cherry"];
for fruit in fruits {
print(fruit);
}
// Process each item
let numbers = [1, 2, 3, 4, 5];
let mut sum: int = 0;
for num in numbers {
sum += num;
}
print(sum); // 15Range Expressions
// Exclusive range: 0..5 means 0, 1, 2, 3, 4
for i in 0..5 {
print(i);
} // Prints: 0, 1, 2, 3, 4
// Inclusive range: 1..=10 means 1 to 10 inclusive
for i in 1..=10 {
print(i);
} // Prints: 1, 2, 3, ..., 10
// Counting backwards
let mut i = 10;
while i >= 0 {
print(i);
i--;
} // Prints: 10, 9, 8, ..., 0Loop Control: Break & Continue
// break: exit loop entirely
for i in 0..100 {
if i == 5 {
break; // Stop the loop
}
print(i);
} // Prints: 0, 1, 2, 3, 4
// continue: skip to next iteration
for i in 0..10 {
if i % 2 == 0 {
continue; // Skip even numbers
}
print(i);
} // Prints: 1, 3, 5, 7, 9
// Find first match and exit
let data = [10, 20, 30, 40];
let mut found = nil;
for item in data {
if item > 25 {
found = item;
break;
}
}
print(found); // 30Nested Loops
// Matrix iteration
for row in 0..3 {
for col in 0..3 {
print("[" + row + "," + col + "]");
}
}
// Breaking out of nested loops
let mut done = false;
for i in 0..10 {
for j in 0..10 {
if i * j == 42 {
done = true;
break;
}
}
if done { break; }
}State Transitions
Managing state changes cleanly with mutable variables and pattern matching.
// State machine pattern
let mut state: string = "idle";
fn transition(current: string, event: string) -> string {
match current {
"idle" => match event {
"start" => "running",
_ => current
},
"running" => match event {
"pause" => "paused",
"stop" => "stopped",
_ => current
},
"paused" => match event {
"resume" => "running",
"stop" => "stopped",
_ => current
},
_ => current
}
}
// Usage
state = transition(state, "start"); // "running"
state = transition(state, "pause"); // "paused"
state = transition(state, "resume"); // "running"Arrays and Maps
Reox provides built-in collections for storing multiple values.
// Arrays
let numbers = [1, 2, 3, 4, 5];
let first = numbers[0]; // Access by index
let count = len(numbers); // Get length: 5
// Modify array (requires mutable)
let mut items = ["a", "b"];
items = push(items, "c"); // ["a", "b", "c"]
let last = pop(items); // "c"
// Maps (key-value pairs)
let mut user = map_new();
user = map_set(user, "name", "Alice");
user = map_set(user, "age", 25);
let name = map_get(user, "name"); // "Alice"
// Check if key exists
let hasEmail = map_has(user, "email"); // falseStructures
Define custom data types with struct.
struct User {
id: int,
name: string,
email: string
}
let user = User {
id: 1,
name: "Swana",
email: "[email protected]"
};
// Access fields
print(user.name); // "Swana"
// Optional chaining (returns nil if nil)
let maybeUser = nil;
print(maybeUser?.name); // nil (no crash)Null Safety
Handle nil values safely with optional chaining and null coalescing.
// Null coalescing: use default if nil
let value = nil;
let result = value ?? "default"; // "default"
// Optional chaining: safe member access
let user = nil;
let name = user?.name ?? "Guest"; // "Guest"
// Chained optional access
let city = user?.address?.city ?? "Unknown";Pattern Matching
Powerful match expressions simplify control flow.
match command {
"save" => save_file(),
"load" => load_file(),
"exit" => return,
_ => print("Unknown command")
}Conditionals
Use if, else if, and else for conditional branching.
let score: int = 85;
if score >= 90 {
print("Excellent!");
} else if score >= 70 {
print("Good job!");
} else {
print("Keep trying!");
}
// Logical operators
if score > 50 and score < 100 {
print("Valid score");
}
if score < 0 or score > 100 {
print("Invalid score");
}
if not is_valid {
print("Not valid");
}Error Handling
Reox provides robust error handling with guard, try/catch, and defer.
// Guard: early exit if condition fails
guard user != nil else {
return;
}
// Defer: cleanup when leaving scope
defer {
close_connection();
}
// Try/catch: handle exceptions
try {
risky_operation();
} catch err {
print("Error: " + err);
}
// Throw an error
throw "Something went wrong";