Nested Structures
Boxes Inside Boxes
You know the three building blocks: sequence, selection, and repetition. The final move that makes them a complete toolkit is beautifully simple: the body of any structure can contain other structures. A loop can hold an IF. An IF can hold a loop. A loop can hold another loop — which holds another IF.
This is nesting, named after Russian dolls, and it is not an advanced trick — it is how all real logic gets expressed. The programs you use are structures nested tens of levels deep, kept sane by functions and indentation.
IF Inside a Loop: Deciding About Every Item
The most common nest in existence. The loop visits every item; the IF decides about each one:
FOR each score IN scores
IF score > 80 THEN
OUTPUT "Honours!"
ENDIF
NEXT
Every list-processing pattern — counting matches, filtering, finding the biggest — is exactly this shape. Notice how the indentation tells the story at a glance: the IF belongs to the loop, the OUTPUT belongs to the IF.
Loop Inside a Loop: Covering a Grid
Now the famous one. How does a program visit every square of a grid — a chessboard, a spreadsheet, every pixel of an image?
FOR row ← 0 TO 7
FOR col ← 0 TO 7
examine square[row][col]
NEXT col
NEXT row
Read it like a clock: the outer counter (row) is the hours hand, moving slowly; the inner counter (col) is the seconds hand, spinning through all its values for every single tick of the outer one. The visiting order: (0,0), (0,1) … (0,7), then (1,0), (1,1)… — row by row, left to right, exactly like reading a page.
Count the work: 8 outer turns × 8 inner turns = 64 visits. That multiplication is the signature of nested loops, and it cuts both ways. It is exactly what you want for a grid — and exactly the squared growth that makes "compare every item with every other item" explode on big data. When you write a loop inside a loop over the same large list, pause and ask whether there is a better way.
The inner limit can even depend on the outer counter:
FOR row ← 1 TO 3
FOR col ← 1 TO row
OUTPUT "*"
NEXT col
OUTPUT newline
NEXT row
Row 1 prints one star, row 2 two, row 3 three — a triangle. Small change, new shape; nested counters are surprisingly expressive.
IF Inside IF: Decisions Behind Decisions
Selection nests too — a question that only makes sense after another question:
IF logged in THEN
IF is admin THEN
show admin panel
ELSE
show normal dashboard
ENDIF
ELSE
show login page
ENDIF
Three outcomes, arranged as a decision tree. (Sharp eyes will spot that logged in AND is admin with Boolean logic can sometimes flatten a nest — when it can, flatter is usually clearer.)
Keeping Nests Readable
Nesting is power, and like all power it can be overdone. Five levels deep, even the author gets lost — which line belongs to which ENDIF? Two habits keep nests tame:
- Indent religiously. The eye should see the structure before the brain reads a word. Every pseudocode example on this page does it.
- Name the inner levels. If the inside of your outer loop has grown to ten lines, extract it into a function:
FOR each row → processRow(row). The nest is still there — but each level now reads as one idea. That is decomposition applied to code layout.
And when a nest misbehaves, a trace table with a column per counter untangles it: watching row and col tick is the fastest way to truly get nested loops.
Try It Yourself
Write nested pseudocode that prints a 5×5 grid where each square shows row * col (a times-table chart!). Then trace the first six visits. Finally, predict: if the grid were 100×100, how many visits — and which single character would you change to get there?
Worked Example — Three Levels Deep: A Seating Chart
Real nesting sometimes goes beyond two levels, and tracing it carefully is the only reliable way to stay oriented. Consider printing a seating chart for a theatre with multiple sections, each with several rows, each row with several seats:
FOR each section IN theatre
FOR row ← 1 TO section.numberOfRows
FOR seat ← 1 TO section.seatsPerRow
IF seat is already booked THEN
OUTPUT "X"
ELSE
OUTPUT "O"
ENDIF
NEXT seat
OUTPUT newline
NEXT row
NEXT section
Four levels are nested here: loop over sections, loop over rows within a section, loop over seats within a row, and an IF deciding what to print for each seat. Notice how each level answers one specific question — "which section?", "which row?", "which seat?", "is it booked?" — and indentation keeps each question visually separate from the others. This is exactly why the "extract to function" advice from earlier in this lesson becomes valuable at this depth: printSection(section) could hide the row-and-seat loops entirely, leaving the outermost loop reading almost like plain English — "for each section, print the section" — with the seating detail tucked safely out of sight.
Key Words
- Nesting — placing one structure inside the body of another
- Outer / inner loop — the slow hand and the fast hand of a nested pair
- Decision tree — nested IFs producing several distinct outcomes
- Indentation — the visual map of nesting depth
- Extract to function — naming an inner level to keep nests readable