Concepts / Variable Scope and Blocks

Variable Scope and Blocks

Good initialization is about timing as well as presence. A variable set up with a real value at the moment it is created cannot be read in a half-finished state.

  • Programming

A Declaration Is Not Yet a Value

A very common early belief is that once a variable has been declared, it is ready to use. A beginner writes a line that names a variable and its type, then moves on to other work, planning to fill in the value later. The declaration looks finished on the page, so leaving the variable as it is seems harmless. This section and the rest of the article correct that belief.

What do you think happens?

A variable is declared with a type but no value is ever given to it. Is the program now safe to read that variable?

  • Yes, because the declaration already set it up

  • No, because the variable has no value the program chose

Reveal answer
Answer:

No, because the variable has no value the program chose

The source's core rule is that a program should not depend on a value that was never chosen. A declaration names the variable and its type, but declaring a variable does not finish the job. Initialization is what gives the variable the value it will hold.

Initialization Gives a Variable Its Value

Declaring a variable does not finish the job. Initialization gives the variable the value it will hold. The source's guidance is that a program should not depend on a value that was never chosen. A variable that exists but has not been initialized sits in an unsettled state: it has a name and a type, yet no value that the programmer selected for it.

The reason this matters is dependence. If a later line of code reads a variable whose value was never chosen, the result depends on something the programmer did not decide. The source does not describe what such a variable holds, so the safe conclusion is that the program should never rely on it. Initializing a variable closes that gap by making the first value an explicit choice.

Key point

Good initialization is about timing as well as presence. A variable set up with a real value at the moment it is created cannot be read in a half-finished state.

Declaring and Assigning Together

The source gives a specific habit: do not declare a variable until you have a value to initialize it with. In practice, the declaration and the first assignment should happen together, close to the place where the value is computed or known. Declaring a variable early, far above the place where it is needed, creates a window in which the variable exists without a meaningful value.

declare totalno value yetdeclare and assigntotal = 0value ready at creationother worktotal still has no valueother worktotal already has a valueassign total = 0first real valueuse totaluse totalthenthenthenthenthen
In what order do declaration, assignment, and first use happen, and how does moving the declaration later remove the gap?

In the early version of the timeline, the variable exists through the whole stretch of other work with no meaningful value, and a reader scanning the code might not notice that gap. In the late version, the declaration and the first value arrive together, so there is no moment where the variable can be read without a real value. Moving the declaration down to the point of assignment removes the gap entirely.

Before
total
# ... many lines of other work ...
total = 0

The variable is named early, but its first real value arrives much later.

After
total = 0
# ... other work that uses total ...

The variable is named and given its first value at the same point, where it is ready to use.

Scope as the Region Where a Variable Is Used

Definition

A variable's scope is the part of the code in which the variable can be used. Keeping that region small means a variable is visible only where it is actually needed, so there are fewer places in the program where it can be misused or accidentally changed.

Blocks nest inside one another. The outer function body is the widest region. A loop body sits inside it, and an if block can sit inside the loop. A variable declared in the innermost block is available only there. The guidance asks you to choose the narrowest region that still lets the variable do its job. The diagram below shows the nesting and where each variable from the example is visible.

Function bodywidest regionLoop bodynested inside function bodyIf blocknested inside loop bodytotalvisible in all three blocksitemvisible in loop and ifblockflagvisible only in if blockcontainscontainsdeclared indeclared indeclared in
Which blocks can see this variable, and which lines outside its block cannot?
Worked example

Choosing the narrowest scope for a temporary value

A function loops over a list of prices and needs a temporary variable to hold the discounted price for each item. Where should the temporary variable be declared?

  1. 1
    Identify where the value is needed

    The discounted price is needed only inside the loop, one item at a time. It is not needed after the loop finishes.

  2. 2
    Find the narrowest block that still works

    The loop body is the smallest region that lets the variable do its job. Declaring it in the function body would make it visible to lines that never use it.

  3. 3
    Declare and assign together

    Inside the loop body, compute the discounted price and declare the variable on the same line, so it is never visible without a value.

Result

The temporary variable is declared inside the loop body with its value computed at the same time, so it is visible only where it is used and is never read before it has a value.

Tracing a Stale Value Across Blocks

A broad scope has a second danger beyond visibility. If a variable is declared in an outer block and used by two separate inner blocks, a value left behind by the first block is still there when the second block starts. The second block may then reuse a stale value that it should not have inherited. The sketch below shows this pattern using a generated example.

pseudocode
Notes on the code
  • total is declared once in the outer region and visible to both loops
  • the first loop leaves total holding 3
  • the second loop starts from that leftover 3 instead of a fresh 0

What do you think happens?

The first loop runs three times, adding 1 each time. The second loop runs two times, adding 1 each time. What does total hold at the end, and what should it hold if the second block were meant to start fresh?

Reveal answer
Answer:

total ends at 5. A fresh second block would have produced 2.

total starts at 0, the first loop brings it to 3, and the second loop adds 2 more to reach 5. The second block was meant to count only its own two passes, but the stale value of 3 carried over from the first block, so the result is wrong by 3.

total = 0before first blocktotal = 3after first blocktotal = 3second block starts here,not at 0total = 5after second blockfirst block adds 3no resetsecond block adds 2
How does a value left in a wide-scope variable from an earlier block get reused by a later block that should have started fresh?

Mistakes Beginners Make

  • Common mistake

    Declaring a variable and planning to fill in its value later

    What it looks like

    A variable is named at the top of a function, and several lines of unrelated work follow before it receives any value.

    Why it fails

    The variable exists during that gap without a value the programmer chose, so the program should not depend on it.

    Do this instead

    Declare and assign together, close to the place where the value is computed or known.

  • Common mistake

    Declaring a variable in an outer block when only an inner block uses it

    What it looks like

    A temporary value needed only inside a loop is declared in the function body above the loop.

    Why it fails

    The variable is visible in places that never use it, which creates more places where it can be misused or changed.

    Do this instead

    Declare it in the narrowest block that still lets it do its job, such as the loop body.

  • Common mistake

    Reusing a wide-scope variable across blocks without starting it fresh

    What it looks like

    The second loop in the generated example adds to a total left over from the first loop.

    Why it fails

    The later block inherits a stale value it should never have seen, and the result is quietly wrong.

    Do this instead

    Narrow the scope so each block has its own variable, or assign a fresh starting value where the second block begins.

  • Common mistake

    Assuming a declared but uninitialized variable is safe to read

Habits for Small, Ready Variables

Best practice

Before you write a declaration, ask whether you already have the value to put in it. If you do, declare and assign on the same line. If you do not, wait until the value is ready rather than naming the variable early.

Best practice

After you write a declaration, ask which blocks actually need the variable. Keep its scope as small as necessary so that it is visible only where it is used. This reduces the number of places in the program where the variable can be misused or accidentally changed.

  • Declare a variable only when you have a value to give it
  • Initialize at the moment of declaration where possible
  • Place the declaration in the narrowest block that still lets it do its job
  • When a later block needs a fresh start, do not reuse a wide-scope variable that holds an earlier block's value

Practice Narrowing a Sketch

MEDIUM

The sketch below declares a variable named result near the top of a function, then uses it in two separate blocks. Rewrite the sketch so that each variable is declared only where its value is ready and its scope is no wider than needed. Explain which block gets its own variable and why.

Sketch: result (declared at top, no value yet) ... first block sets result = 4 and uses it ... second block adds 1 to result and uses it.

Hints
  • Ask whether the second block needs the value from the first block, or whether it should start with its own value.
  • A declaration and its first assignment should happen together, close to where the value is known.
  • If the two blocks do not need to share a value, give each block its own variable with its own scope.

Key Takeaways

  • A declared variable is not ready to use until initialization gives it a value the programmer chose; a program should not depend on a value that was never chosen.
  • Declare a variable only when a value is ready to assign to it, and declare and assign together where possible.
  • A variable's scope is the part of the code where it can be used, and keeping that scope as small as necessary limits where it can be misused or changed.
  • A variable in a wide scope can carry a stale value from one block into a later block that should have started fresh, so narrow the scope or reinitialize where a fresh start is needed.

Related concepts

More concepts starting with V