Control Flow in Nim
Master conditionals, case statements, and loops in Nim - including if-expressions, ranges, iterators, and labeled breaks with Docker-ready examples
Control flow determines the order in which your program executes statements - which branches it takes and how many times it repeats work. Nim gives you a familiar, Python-like set of tools (if, case, for, while) but with a twist that reflects its multi-paradigm nature: most control structures are also expressions that produce values.
Because Nim is statically typed and expression-oriented, an if or case can sit on the right-hand side of an assignment, eliminating the need for a separate ternary operator. Its for loops iterate over iterators rather than manual index counters, and its case statement requires you to handle every possibility - the compiler enforces exhaustiveness, catching missing branches before your program ever runs.
In this tutorial you’ll learn conditional branching with if/elif/else, multi-way dispatch with case, iteration with for and while, the break/continue loop controls (including labeled breaks for nested loops), and how to use control structures as value-producing expressions.
Conditionals: if, elif, else
Nim’s if statement uses indentation rather than braces, and a colon ends each condition. The same construct doubles as an expression.
Create a file named conditionals.nim:
| |
Because 25 fails every earlier test, control falls through to the else branch. The second if is used as an expression: it evaluates to a string that is bound to status. This is Nim’s idiomatic replacement for the ?: ternary found in C-like languages.
Multi-Way Branching: case
When you need to dispatch on the value of a single variable, case is cleaner than a chain of elifs. Branches can list multiple values, and the case is checked for exhaustiveness by the compiler - here an else covers any remaining values.
Create a file named case_statement.nim:
| |
With day equal to 3, the second branch matches and prints Weekday. The character case then matches 'B' and prints Good. Note that branches do not “fall through” as they do in C - each branch is self-contained, with no break required.
Loops: for and while
Nim’s for loop iterates over an iterator - a range, a sequence, or a custom generator. The while loop repeats as long as its condition holds. Built-in iterators like countdown let you walk values in reverse.
Create a file named loops.nim:
| |
The 1..5 syntax builds an inclusive range. Iterating a sequence directly yields each element, while the two-variable form (index, fruit) yields the position alongside the value. The while loop uses dec n to decrement, and countdown(5, 1) produces 5, 4, 3, 2, 1 without any manual bookkeeping.
Loop Control: break, continue, and labeled blocks
continue skips to the next iteration; break exits the loop entirely. To break out of nested loops at once, label a block and break that label directly.
Create a file named loop_control.nim:
| |
In the first loop, even numbers are skipped by continue, and once i exceeds 7 the break ends iteration - so only the odd numbers up to 7 print. In the nested loops, break outer exits both loops the moment the product passes 4, jumping straight out of the labeled block.
Control Flow as Expressions
Nim’s expression-oriented design lets case and if produce values directly. This keeps mapping logic compact and readable.
Create a file named expressions.nim:
| |
The case expression evaluates score div 10 (which is 8) and yields "B", assigning it to letter. FizzBuzz then exercises if/elif/else inside a loop, checking divisibility by 15 first so that multiples of both 3 and 5 are handled before the narrower cases.
Running with Docker
You can compile and run every example without installing Nim locally. Each nim c -r command compiles the file to a native binary and runs it immediately.
| |
Expected Output
Running conditionals.nim:
Warm
Status: comfortable
Running case_statement.nim:
Weekday
Good
Running loops.nim:
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
Fruit: apple
Fruit: banana
Fruit: cherry
0: apple
1: banana
2: cherry
Countdown: 3
Countdown: 2
Countdown: 1
Down: 5
Down: 4
Down: 3
Down: 2
Down: 1
Running loop_control.nim:
Odd: 1
Odd: 3
Odd: 5
Odd: 7
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
2 * 1 = 2
2 * 2 = 4
Breaking at 2x3
Running expressions.nim:
Grade: B
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
Key Concepts
- Expression-oriented control flow -
ifandcasereturn values, so Nim has no need for a separate ternary operator; assign their result directly to a variable. - Exhaustive
case- The compiler requires every possible value to be handled; use anelsebranch to cover the remainder, and remember branches never fall through. - Iterator-based
forloops - Loops iterate over ranges (1..5), sequences, and iterators likecountdown; the two-variable form yields index and value together. - Inclusive ranges -
a..bincludes both endpoints, unlike the exclusive ranges in some other languages. breakandcontinue-continueskips to the next iteration;breakexits the innermost loop.- Labeled breaks - Wrap nested loops in a named
blockand usebreak <label>to escape all of them in a single jump. - Indentation defines blocks - Like Python, Nim uses significant whitespace and a trailing colon rather than braces to delimit control-flow bodies.
Running Today
All examples can be run using Docker:
docker pull nimlang/nim:alpine
Comments
Loading comments...
Leave a Comment