Language Guide
Everything you need to start programming in Zym. This guide covers the basics — variables, types, operators, control flow, functions, and more — with brief examples for each feature. For deeper exploration, each section links to a dedicated page with full documentation and edge cases.
Variables
Variables are declared with var. Zym is dynamically typed — any variable can hold any value.
var name = "Zym" var version = 1 var active = true var nothing = null
Multiple variables can be declared on a single line:
var x = 1, y = 2, z = 3
Types
Zym has the following built-in types:
| Type | Examples |
|---|---|
number | 42, 3.14, -7, 1e10 |
string | "hello", "café" |
boolean | true, false |
null | null |
list | [1, 2, 3] |
map | { name: "Alice", age: 30 } |
struct | User-defined compound types |
enum | User-defined enumeration types |
function | Named, anonymous, and arrow functions |
Number literals
Numbers support decimal, hexadecimal, and binary literals. Underscores can be used as separators for readability.
// Decimal var a = 42 var b = 3.14 var c = 1e10 // Hexadecimal (0x prefix) var hex = 0xFF // 255 var hex2 = 0xABCD // 43981 // Binary (0b prefix) var bin = 0b1010 // 10 var bin2 = 0b11111111 // 255 // Underscore separators (ignored by parser) var large = 1_000_000 // 1000000 var hexSep = 0xAB_CD // 43981 var binSep = 0b1111_0000 // 240
Operators
Arithmetic
10 + 3 // 13 10 - 3 // 7 10 * 3 // 30 10 / 3 // 3.333... 10 % 3 // 1
Comparison
x == y // equal x != y // not equal x < y // less than x > y // greater than x <= y // less or equal x >= y // greater or equal
Logical
a and b // logical AND a or b // logical OR !a // logical NOT
String concatenation
"hello" + " world" // "hello world"
Truthiness
Zym’s truthiness rules for conditional expressions:
| Type | Truthy | Falsy |
|---|---|---|
bool | true | false |
null | — | always falsy |
number | non-zero | 0 |
| all others | always truthy | — |
Strings, lists, maps, structs, and functions are always truthy — even empty ones.
Semicolons
Semicolons are optional. You may use them or omit them — Zym handles both styles.
var a = 1 var b = 2; var c = a + b
Control Flow
Zym provides the standard control flow constructs you’d expect. Conditions must be wrapped in parentheses and bodies in braces.
if (x > 0) { print("positive") } else if (x == 0) { print("zero") } else { print("negative") }
// while loop while (x > 0) { x = x - 1 } // do-while — always runs at least once do { x = x + 1 } while (x < 10) // for loop for (var i = 0; i < 10; i = i + 1) { print(i) }
switch (value) { case 1: print("one") break case 2: print("two") // falls through to case 3 case 3: print("two or three") break default: print("other") }
Cases fall through by default — use break to exit. Each case can have its own block scope with braces.
Loops support break to exit early and continue to skip to the next iteration. Zym also has goto — a safe jump that performs proper cleanup before transferring control.
goto skip x = 999 // never reached skip: x = x + 1 // execution continues here
→ Full details: Control Flow — nested loops, outward scope jumps, state machines, jump tables, and more.
Functions
Functions are declared with func. They are first-class values — you can store them in variables, pass them as arguments, and return them from other functions.
// Named function func add(a, b) { return a + b } // Arrow function var double = (x) => x * 2 // Anonymous function var greet = func(name) { return "Hello, " + name }
Functions are hoisted — you can call a function before its declaration in the same scope. Zym also supports overloading by arity (number of parameters):
func greet() { return "Hello!" } func greet(name) { return "Hello, " + name } greet() // "Hello!" greet("Zym") // "Hello, Zym"
→ Full details: Functions — closures, dispatchers, shared/independent closure state, and more.
Structs & Enums
Structs are user-defined compound types with named fields. Enums are fixed sets of named variants with type-safe comparison.
struct Point { x; y } var p = Point(10, 20) // positional init p.x // 10 p.y = 30 // field mutation
enum Color { RED, GREEN, BLUE } var c = Color.RED c == Color.RED // true c == Color.BLUE // false
→ Full details: Structs & Enums — named init, nested structs, spread, schema scope hoisting, enum scoping, and more.
Memory Semantics
Zym gives you explicit control over how values pass between scopes with four keywords:
| Keyword | What it does |
|---|---|
ref | Creates an alias — writes go through to the original |
val | Deep-copies the value (but refs keep the same target) |
slot | Binds to the variable slot — can rebind refs |
clone | True isolation — deep-copies both value and any refs |
var x = 42 var r = ref x // r is an alias for x r = 100 // x is now 100 func safe(val data) { data[0] = 999 // local copy — caller unchanged } var copy = clone x // fully independent copy
→ Full details: Memory Semantics — ref flattening, val vs clone with references, slot rebinding, and more.
Spread Operator
The spread operator (...) expands a list, map, or struct inline. It’s useful for combining collections and creating modified copies.
var a = [1, 2] var b = [3, 4] var combined = [...a, ...b] // [1, 2, 3, 4] var defaults = { color: "red", size: 10 } var custom = { ...defaults, size: 20 } // override size var p2 = Point{...p1, .y = 99} // struct spread with override
→ Full details: Spread Operator — override ordering, nested spread, function argument spreading, and more.
Tail-Call Optimization
Zym supports opt-in tail-call optimization via the @tco directive. This lets recursive functions run in constant stack space, enabling deep recursion without overflow.
@tco aggressive func factorial(n, acc) { if (n <= 1) return acc return factorial(n - 1, n * acc) } factorial(100000, 1) // no stack overflow
Three active modes: aggressive (any tail call), safe (compile-time verified only), and smart (compile-time first, runtime fallback). Use off to disable for debugging.
→ Full details: Tail-Call Optimization — mode comparison, mutual recursion, accordion patterns, closures with TCO, and more.
Collections
Zym has two built-in collection types: lists (ordered, indexed) and maps (key-value pairs).
// Lists var nums = [1, 2, 3] nums[0] // 1 push(nums, 4) // [1, 2, 3, 4] length(nums) // 4 // Maps var user = { name: "Alice", age: 30 } user["name"] // "Alice" user.age // 30
→ See the List API and Map API for all available functions.
Macros & Preprocessor
Zym includes a built-in preprocessor that runs before compilation. Use #define to create compile-time constants, function-like macros, and multi-line block macros. Conditional compilation directives (#if, #ifdef, #ifndef) let you include or exclude code based on configuration.
#define MAX_SIZE 100 #define SQUARE(x) x * x var arr = [null] * MAX_SIZE var result = SQUARE(5) // expands to: 5 * 5 #ifdef DEBUG print("Debug mode") #endif
→ Full details: Macros & Preprocessor — block macros, conditional compilation, expression evaluation, common patterns, and more.
Modules
Zym’s module system lets you split code across files. Use import("path") to load a module. Modules are cached by default — every import of the same file returns the same instance, sharing state automatically. Use the "use fresh" directive to opt out.
// math_utils.zym func add(a, b) { return a + b } return { add } // main.zym var math = import("math_utils.zym") print(math.add(2, 3)) // 5
→ Full details: Modules — caching, "use fresh", named imports, path resolution, circular detection, and common patterns.
Deep Dive
Each language feature above has its own dedicated page with comprehensive documentation, examples, and edge cases:
| Topic | What’s Covered |
|---|---|
| Control Flow | if/else, while, do-while, for loops, switch statements, break & continue, goto/labels, state machines, jump tables |
| Functions | Named functions, hoisting, overloading by arity, anonymous functions, arrow syntax, closures, dispatchers |
| Memory Semantics | ref (aliasing), val (deep copy), slot (rebinding), clone (true isolation), ref flattening |
| Structs & Enums | Struct declaration, positional/named init, field mutation, nested structs, schema hoisting; enum variants, type safety, scoping |
| Tail-Call Optimization | @tco directive, modes (aggressive/safe/smart/off), mutual recursion, accordion & shattered patterns |
| Spread Operator | List spread, map spread, struct spread, override ordering, function argument spreading |
| Macros & Preprocessor | #define macros, function-like macros, block macros (##define), conditional compilation, #if/#ifdef/#ifndef, expression evaluation |
| Modules | import("path"), module caching, "use fresh" directive, named imports, path resolution, circular detection |