Skip to main content

Control Flow

Zynx provides a familiar set of block-based control flow structures. This section describes conditional branching, loops, and pattern matching in Zynx, with short examples for each.

Branching

if / else

Use if, else if, and else blocks with boolean conditions.

if x > 0 {
os.write("positive\n");
} else if x < 0 {
os.write("negative\n");
} else {
os.write("zero\n");
}

Loops

while

while repeats a block as long as its condition is true.

let i = 0;
while i < 3 {
os.write("{i}\n");
i += 1;
}

for

for iterates over collections, strings, or ranges.

// Arrays and slices
for val in nums { ... }
for idx, val in nums { ... }

// Ranges
for i in 0...3 { /* inclusive */ }
for i in 0..<3 { /* exclusive */ }

// Custom iterables
for v in MyRange { curr: 0, end: 3 } { ... }

Pattern Matching

match

Use match to compare a value against patterns. match is exhaustive and can be used as an expression.

let desc = match x {
1 => "one",
2 => "two",
_ => "other",
};

Block Arms

Use blocks for complex logic. In expression matches, each arm must evaluate to a value.

let result = match x {
0 => "zero",
_ => {
let y = x * 2;
if y > 10 {
"large"
} else {
"non-zero"
}
},
};

Resource Management

with

The with statement is used for scoped resource management. It ensures that a value's drop method is called immediately when the block exits, even if the value would normally live longer. It is commonly used for files, locks, or any resource requiring deterministic cleanup.

with make_resource() as r {
r.use();
} // r.drop() is called here

The as binding is optional if you only need the side effects of the scoped lifetime.

with lock.acquire() {
// Critical section
} // lock is released (dropped) here

Key Characteristics

  • Deterministic Cleanup: The resource is dropped exactly at the end of the with block.
  • Scoping: The variable bound via as is only available within the block.
  • Nesting: with statements can be nested to manage multiple resources with clear destruction ordering (innermost first).
with open_file("input.txt") as f1 {
with open_file("output.txt") as f2 {
f2.write(f1.read_all());
} // f2 dropped here
} // f1 dropped here