Control Flow
Control flow statements allow you to control the execution order of your program. Twinkies supports conditional statements, loops, and jump statements.
If Statements
The if statement executes code conditionally:
if (condition) {
// Code executed if condition is true
}
Basic If
let x: int = 10;
if (x > 5) {
print("x is greater than 5");
}
If-Else
let x: int = 10;
if (x > 5) {
print("x is greater than 5");
} else {
print("x is not greater than 5");
}
If-Else If-Else
let score: int = 85;
if (score >= 90) {
print("Grade: A");
} else if (score >= 80) {
print("Grade: B");
} else if (score >= 70) {
print("Grade: C");
} else {
print("Grade: F");
}
Condition Types
The condition can be:
- Boolean variable:
if (flag) { ... } - Comparison:
if (x > 5) { ... } - Boolean expression:
if (x > 5 && y < 10) { ... } - Function call returning bool:
if (is_prime(n)) { ... }
let x: int = 10;
let y: int = 5;
let flag: bool = true;
if (x > y) { ... } // Comparison
if (flag) { ... } // Boolean variable
if (x > 5 && y < 10) { ... } // Boolean expression
if (x == 10 || y == 5) { ... } // Logical OR
While Loops
The while loop repeats code while a condition is true:
while (condition) {
// Code executed while condition is true
}
Basic While Loop
let i: int = 0;
while (i < 10) {
print(i);
i = i + 1;
}
Countdown Example
let count: int = 10;
while (count > 0) {
print(count);
count = count - 1;
}
print("Blast off!");
Infinite Loops
Be careful with conditions that are always true:
while (true) {
// Infinite loop - use break to exit
// ...
}
Break Statement
The break statement exits the innermost loop immediately:
let i: int = 0;
while (i < 10) {
if (i == 5) {
break; // Exit loop when i reaches 5
}
print(i);
i = i + 1;
}
// Prints: 0, 1, 2, 3, 4
Break in Nested Loops
break only exits the innermost loop:
let i: int = 0;
while (i < 3) {
let j: int = 0;
while (j < 3) {
if (j == 1) {
break; // Only exits inner loop
}
print(i, j);
j = j + 1;
}
i = i + 1;
}
Continue Statement
The continue statement skips the rest of the current loop iteration:
let i: int = 0;
while (i < 10) {
i = i + 1;
if (i == 5) {
continue; // Skip printing 5
}
print(i);
}
// Prints: 1, 2, 3, 4, 6, 7, 8, 9, 10
Continue Example
let i: int = 0;
while (i < 10) {
i = i + 1;
if (i % 2 == 0) {
continue; // Skip even numbers
}
print(i); // Only prints odd numbers
}
// Prints: 1, 3, 5, 7, 9
Return Statement
The return statement exits a function and optionally returns a value:
func check_positive(x: int) -> bool {
if (x > 0) {
return true; // Early return
}
return false;
}
Return Without Value
return can be used without a value:
func modify(x: int) -> int {
x = 100;
return; // No value - this is allowed!
}
Nested Control Flow
Control flow statements can be nested:
let i: int = 0;
while (i < 10) {
if (i % 2 == 0) {
print(i, "is even");
} else {
print(i, "is odd");
}
i = i + 1;
}
Complex Nested Example
func find_prime_in_range(start: int, end: int) -> int {
let i: int = start;
while (i <= end) {
if (is_prime(i)) {
return i; // Found first prime
}
i = i + 1;
}
return -1; // No prime found
}
Common Patterns
Input Validation Loop
let choice: int = input();
while (choice < 1 || choice > 5) {
print("Invalid choice! Enter 1-5: ");
choice = input();
}
Search Loop
let arr: int[10];
let target: int = 42;
let found: bool = false;
let i: int = 0;
while (i < 10 && !found) {
if (arr[i] == target) {
found = true;
print("Found at index", i);
}
i = i + 1;
}
Menu Loop
let choice: int = 0;
while (choice != 4) {
print("1. Option 1");
print("2. Option 2");
print("3. Option 3");
print("4. Exit");
choice = input();
if (choice == 1) {
// Handle option 1
} else if (choice == 2) {
// Handle option 2
} else if (choice == 3) {
// Handle option 3
}
}
Control Flow with Arrays
Iterating Over Arrays
let arr: int[5];
let i: int = 0;
// Initialize array
while (i < 5) {
arr[i] = i * 2;
i = i + 1;
}
// Print array
i = 0;
while (i < 5) {
print(arr[i]);
i = i + 1;
}
Finding Maximum
let arr: int[10];
let max: int = arr[0];
let i: int = 1;
while (i < 10) {
if (arr[i] > max) {
max = arr[i];
}
i = i + 1;
}
print("Maximum:", max);
Error Handling Patterns
Early Return Pattern
func divide(a: int, b: int) -> int {
if (b == 0) {
return 0; // Early return for error case
}
return a / b;
}
Guard Clauses
func process(x: int) -> int {
if (x < 0) {
return 0; // Guard clause
}
if (x > 100) {
return 100; // Guard clause
}
// Main logic here
return x * 2;
}
Best Practices
- Use meaningful conditions - Make conditions clear and readable
- Avoid deep nesting - Use early returns or break complex logic into functions
- Use break/continue judiciously - They can make code harder to follow
- Always initialize loop variables - Ensure loop variables are properly initialized
- Check loop termination - Make sure loops will eventually terminate
- Use braces - Always use braces even for single-statement blocks
Common Pitfalls
Infinite Loops
let i: int = 0;
while (i < 10) {
print(i);
// Forgot to increment i - infinite loop!
}
Off-by-One Errors
let i: int = 0;
while (i <= 10) { // Should be i < 10 for 0-9
print(i);
i = i + 1;
}
Break/Continue Outside Loops
if (x > 5) {
break; // ✗ Error: break outside loop
}
Next Steps
- Learn about Arrays and Strings for loop patterns with arrays
- Read Functions for using control flow in functions
- Check Examples Guide for real-world control flow examples
