Programming · foundation
Variables and scope
A variable is a language-defined binding between a name and a value, storage location, or object reference. Scope is the region of program text or execution context in which a particular binding can be resolved by that name.
Why it matters
Scope determines which value code reads, where names can collide, what a closure captures, and whether changing a name affects shared state or merely creates another binding.
Mental model
How to reason about variables and scope
Name lookup searches the environment prescribed by the language, often moving from an inner lexical scope toward enclosing scopes. A nearer binding can shadow a farther one without modifying it.
Analogy
Scope resembles labelled drawers in nested rooms: code checks the nearest room's drawer first, then enclosing rooms according to the building's lookup rules.
Examples
See the boundary, not just the happy path
Worked example · Local binding shadows an outer name
x = 'outer'
def show():
x = 'inner'
return xIn Python, assigning x in show makes it local to that function unless declared otherwise. Calling show returns inner while the module-level x remains outer.
Worked example · Closure resolves an enclosing binding
def multiplier(factor):
return lambda value: factor * valueThe returned function refers to factor from its enclosing lexical scope. The binding remains available through the closure after multiplier has returned.
Useful contrast · Shell environment is a different mechanism
export PORT=8080An environment variable is process configuration inherited by child processes. It is not automatically a lexical variable in a programming language, even when both use a name such as PORT.
Common mistakes
Misconceptions to remove early
Equating scope with lifetime
Scope governs where a name can be resolved; lifetime governs how long a value or storage remains alive. A closure can keep captured state alive after the original call's local scope has finished.
Mistaking shadowing for mutation
Creating a nearer binding with the same name can leave the outer binding untouched. Mutation changes the state of an existing mutable object or location.
Quick check
Can you predict the result?
1. What does lexical shadowing do?
- • It makes a nearer binding with the same name take precedence in its scope.
- • It deletes every outer binding with that name.
- • It converts the variable into an environment variable.
2. How can a captured value outlive the function call that created its local binding?
Keep building