For statements#
Code Example
Runnable Example in Jac and JacLib
# For Statements
# Basic for-in loop
with entry {
for x in [1, 2, 3] {
print(x);
}
# For-in with range
for i in range(5) {
print(i);
}
# For-to-by loop
for i = 0 to i < 5 by i += 1 {
print(i);
}
# For-to-by counting down
for i = 10 to i > 0 by i -= 1 {
print(i);
}
# For-to-by with different step
for i = 0 to i < 10 by i += 2 {
print(i);
}
# For with else clause (executes when loop completes normally)
for x in [1, 2, 3] {
print(x);
} else {
print("completed");
}
# For with break (else clause skipped)
for x in range(10) {
if x == 3 {
break;
}
print(x);
} else {
print("not reached");
}
# For with continue
for x in range(5) {
if x % 2 == 0 {
continue;
}
print(x);
}
# Nested for loops
for i in range(3) {
for j in range(2) {
print(f"{i},{j}");
}
}
# For-in over string
for char in "abc" {
print(char);
}
}
# For-in over dictionary keys
glob d = {"a": 1, "b": 2};
with entry {
for key in d {
print(key);
}
# Mix for-in and for-to-by in nested loops
for i in ["a", "b"] {
for j = 0 to j < 2 by j += 1 {
print(f"{i}{j}");
}
}
}
# Tuple unpacking
glob pairs = [(1, 2), (3, 4), (5, 6)];
with entry {
for (a, b) in pairs {
print(f"a={a}, b={b}");
}
}
# List unpacking (uses tuple syntax in Jac)
glob matrix = [[1, 2, 3], [4, 5, 6]];
with entry {
for (x, y, z) in matrix {
print(f"x={x}, y={y}, z={z}");
}
}
# Nested tuple unpacking
glob nested = [("alice", (10, 20)), ("bob", (30, 40))];
with entry {
for (name, (x, y)) in nested {
print(f"{name}: x={x}, y={y}");
}
}
# Star unpacking (rest of elements)
glob items = [(1, 2, 3, 4), (5, 6, 7, 8)];
with entry {
for (first, *rest) in items {
print(f"first={first}, rest={rest}");
}
}
# Star unpacking in middle
glob sequences = [(1, 2, 3, 4, 5), (6, 7, 8, 9, 10)];
with entry {
for (first, *middle, last) in sequences {
print(f"first={first}, middle={middle}, last={last}");
}
}
# Dictionary items unpacking
glob data = {
"name": "Alice",
"age": 30,
"city": "NYC"
};
with entry {
for (key, value) in data.items() {
print(f"{key}: {value}");
}
}
# Enumerate with unpacking
glob coords = [(10, 20), (30, 40), (50, 60)];
with entry {
for (i, (x, y)) in enumerate(coords) {
print(f"Point {i}: ({x}, {y})");
}
}
# Zip with unpacking
glob xs = [1, 2, 3],
ys = [10, 20, 30];
with entry {
for (x, y) in zip(xs, ys) {
print(f"x={x}, y={y}");
}
}
# Complex: enumerate + zip + unpacking
glob as_ = [1, 2, 3],
bs = [4, 5, 6],
cs = [7, 8, 9];
with entry {
for (i, (a, b, c)) in enumerate(zip(as_, bs, cs)) {
print(f"Index {i}: a={a}, b={b}, c={c}");
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
Jac Grammar Snippet
Description
For Statements in Jac
For loops provide iteration over collections and sequences. Jac offers two distinct loop styles: the for-in pattern for iterating collections, and the for-to-by pattern for explicit counter control.
Basic For-In Loop
The simplest iteration pattern uses for-in to loop through collections (lines 5-7):
The loop variable x takes each value from the list in sequence. This works with any iterable: lists, tuples, sets, dictionaries, strings, and ranges.
For-In with Range
Lines 10-12 demonstrate using range() to generate numeric sequences. This produces values 0 through 4. The range() function is lazy, generating values on demand rather than creating a full list in memory.
For-To-By Loop (Jac's C-Style Loop)
Lines 15-17 show Jac's unique three-part loop syntax. This loop has three components:
- Initialization (
i=0): Sets the starting value - Condition (
to i<5): Loop continues while true - Increment (
by i+=1): Executed after each iteration
This provides explicit control similar to C's for(int i=0; i<5; i++) but with more readable syntax.
Counting Down
Line 20-22 shows decrementing with for-to-by. The loop starts at 10, continues while i>0, and decrements by 1 each iteration.
Custom Step Values
Lines 25-27 demonstrate non-unit steps. This produces even numbers: 0, 2, 4, 6, 8.
For-Else Clause
Lines 30-34 introduce the else clause, which executes only if the loop completes normally (without break). This pattern is useful for search operations: if you break when finding an item, the else clause indicates "not found."
Breaking Out of Loops
Lines 37-44 show how break exits the loop immediately and skips the else clause. Output: 0, 1, 2 (the else block doesn't execute).
Continue Statement
Lines 47-52 demonstrate continue, which skips to the next iteration. This prints only odd numbers: 1, 3.
Nested Loops
Lines 55-59 show loops within loops. Both for-in and for-to-by loops can be nested and mixed freely.
Iterating Strings
Lines 62-64 demonstrate character iteration. Strings are iterable sequences of characters.
Dictionary Iteration
Lines 67-70 show that iterating a dictionary yields its keys. Use .values() for values or .items() for key-value pairs.
Mixed Loop Types
Lines 73-77 demonstrate combining different loop styles. The outer loop uses for-in while the inner uses for-to-by.
Unpacking in For Loops
Jac supports Python-style unpacking to destructure elements during iteration.
Tuple/List Unpacking:
Nested Unpacking:
Star Unpacking:
for (first, *rest) in items {
print(f"first={first}, rest={rest}");
}
for (first, *middle, last) in sequences {
print(f"first={first}, middle={middle}, last={last}");
}
With Built-in Functions:
for (key, value) in data.items() {
print(f"{key}: {value}");
}
for (i, (x, y)) in enumerate(coords) {
print(f"Point {i}: ({x}, {y})");
}
for (x, y) in zip(xs, ys) {
print(f"x={x}, y={y}");
}
Loop Control Flow Summary
| Statement | Effect | Else Clause Behavior |
|---|---|---|
break |
Exit loop immediately | Skipped |
continue |
Skip to next iteration | Not affected |
| Normal completion | Loop finishes naturally | Executes (if present) |
For Loop Variations
| Form | Syntax | Use Case |
|---|---|---|
| for-in | for var in iterable |
Iterate collections |
| for-to-by | for i=start to cond by step |
Explicit counter control |
| for-else | for ... { } else { } |
Detect uninterrupted completion |
| unpacking | for (a, b) in pairs |
Destructure elements |
Unpacking Patterns
| Pattern | Example |
|---|---|
| Simple | for (a, b) in pairs |
| Nested | for (a, (b, c)) in data |
| Star (end) | for (first, *rest) in items |
| Star (middle) | for (a, *mid, z) in items |
| Dict items | for (k, v) in d.items() |
| Enumerate | for (i, val) in enumerate(lst) |
| Zip | for (x, y) in zip(xs, ys) |
Loop Flow Visualization
flowchart TD
Start([Start For Loop]) --> Check{Condition<br/>True?}
Check -->|Yes| Body[Execute Body]
Body --> Continue{Continue<br/>Statement?}
Continue -->|Yes| Update
Continue -->|No| Break{Break<br/>Statement?}
Break -->|Yes| End([Exit Loop])
Break -->|No| Update[Update/Next Item]
Update --> Check
Check -->|No| Else{Else<br/>Clause?}
Else -->|Yes, No Break| ElseBody[Execute Else]
Else -->|No| End
ElseBody --> End
Common Patterns
Filtering during iteration:
Aggregating values:
Finding with for-else:
Processing paired data:
Key Differences from Python
- Braces required: Jac uses
{ }for loop bodies, not indentation - Semicolons required: Each statement ends with
; - For-to-by syntax: Unique to Jac, provides C-style explicit control
- Same else clause: Works identically to Python
- Same unpacking: Tuple, list, and star unpacking work like Python