Nested Structures

8 min✏️ Quiz at the end

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:

  1. Indent religiously. The eye should see the structure before the brain reads a word. Every pseudocode example on this page does it.
  2. 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