Control Flow in Ada
Learn conditionals, loops, and case statements in Ada with practical Docker-ready examples using the GNAT compiler
Control flow defines the order in which statements execute in a program. Ada provides a rich set of control structures designed with safety and readability in mind, reflecting its heritage as a language built for long-lived, mission-critical software.
As a strongly typed multi-paradigm language, Ada’s control flow constructs are notably explicit: every block has a matching end clause, loops can be named for clarity, and the case statement requires exhaustive coverage of all possible values. This verbosity is deliberate — it makes intent obvious to anyone reading the code years later and helps the compiler catch logical gaps early.
In this tutorial, you’ll learn how Ada handles conditionals with if/elsif/else, how the case statement enforces exhaustive matching, and the three forms of loops Ada provides: loop, while, and for. You’ll also see how to control loop execution with exit and how Ada’s named loops make complex iteration patterns readable.
If/Elsif/Else Statements
The if statement in Ada uses the keywords then, optional elsif branches, an optional else, and a closing end if. Note the spelling: it’s elsif, not elseif or else if.
Create a file named conditionals.adb:
| |
Notice that Ada uses and, or, and not as boolean operators — not &&, ||, and !. For short-circuit evaluation, Ada provides and then and or else, which only evaluate the right-hand side when needed.
Case Statements
The case statement is Ada’s switch construct. Unlike C-style switches, Ada’s case requires that every possible value of the selector be covered — either by explicit when branches or by a when others clause. The compiler enforces this exhaustiveness check.
Create a file named case_example.adb:
| |
The | operator combines multiple values in one branch, and ranges like when 1 .. 5 => work for discrete types. There is no fall-through — each branch ends implicitly without needing a break statement.
Loops: Basic, While, and For
Ada provides three loop forms, all built on the fundamental loop/end loop construct. The plain loop is an infinite loop you exit explicitly. Prefixing it with while adds a top-tested condition, and for provides counted iteration.
Create a file named loops.adb:
| |
The for loop variable is implicitly declared, has the type of the range, and is read-only within the loop body — you cannot assign to I. This is one of Ada’s safety features: the loop counter cannot be accidentally modified to corrupt the iteration.
Named Loops and Exit Control
Ada lets you give loops names, which is invaluable when exiting nested loops. The exit statement can target a specific named loop, eliminating the need for sentinel variables or goto.
Create a file named named_loops.adb:
| |
The loop name Search is declared with a colon before the loop and repeated after end loop. The exit Search statement breaks out of both the inner and outer loops in one step. Ada has no continue keyword — to skip to the next iteration, you use an if block or goto with a label at the end of the loop body (rarely needed).
Running with Docker
Pull the GNAT image and compile each example with gnatmake:
| |
Expected Output
Running conditionals:
Score: 87 -> Grade B
Result: Passing
Running case_example:
It's a weekday - time to work
A regular day
Running loops:
Plain loop counting to 3:
1
2
3
Sum 1..5 = 15
Squares from 1 to 4:
1
4
9
16
Counting down:
3
2
1
Running named_loops:
Found 42 at row 2, col 2
Key Concepts
if/elsif/else/end if— Ada useselsif(one word) and always closes withend if. Boolean operators areand,or,not, plus short-circuitand then/or else.caseis exhaustive — Every possible value of the selector must be handled, either explicitly or viawhen others. The compiler enforces this.- Three loop forms — Plain
loop(infinite, exited explicitly),while ... loop(top-tested), andfor I in range loop(counted iteration over a discrete range). forcounters are immutable — The loop variable is read-only inside the body, preventing a common class of off-by-one bugs.reversekeyword — Iterate ranges backwards withfor I in reverse 1 .. 10 loop.- Named loops with
exit Name— Label loops to break out of nested iteration cleanly without flags orgoto. exit whencondition — A concise way to test an exit condition at any point in the loop body.- No fall-through, no
continue—casebranches don’t fall through, and Ada deliberately omitscontinueto encourage clearer loop structure.
Running Today
All examples can be run using Docker:
docker pull codearchaeology/ada:latest
Comments
Loading comments...
Leave a Comment