In computer programming, the scope of a name binding (an association of a name to an entity, such as a variable) is the part of a program in which the name binding is valid. In other words, a scope is where a name can be used to refer to an entity. In other parts of the program, the name may refer to a different entity (it may have a different binding), or to nothing at all (it may be unbound). Scope helps prevent name collisions by allowing the same name to refer to different objects – as long as the names have separate scopes. The scope of a name binding is also known as the visibility of an entity, particularly in older or more technical literature—this is in relation to the referenced entity, not the referencing name.
The term "scope" is also used to refer to the set of all name bindings that are valid within a part of a program or at a given point in a program, which is more correctly referred to as context or environment.
Strictly speaking and in practice for most programming languages, "part of a program" refers to a portion of source code (area of text), and is known as lexical scope. In some languages, however, "part of a program" refers to a portion of run time (period during execution), and is known as dynamic scope. Both of these terms are somewhat misleading—they misuse technical terms, as discussed in the definition—but the distinction itself is accurate and precise, and these are the standard respective terms. Lexical scope is the main focus of this article, with dynamic scope understood by contrast with lexical scope.
In most cases, name resolution based on lexical scope is relatively straightforward to use and to implement, as in use one can read backwards in the source code to determine to which entity a name refers, and in implementation one can maintain a list of names and contexts when compiling or interpreting a program. Difficulties arise in name masking, forward declarations, and hoisting, while considerably subtler ones arise with non-local variables, particularly in closures.
Definition The strict definition of the (lexical) "scope" of a name (identifier) is unambiguous: lexical scope is "the portion of source code in which a binding of a name with an entity applies". This is virtually unchanged from its 1960 definition in the specification of ALGOL 60. Representative language specifications follow:
ALGOL 60 (1960)"Report on the Algorithmic Language Algol 60", 2.7. Quantities, kinds and scopes The following kinds of quantities are distinguished: simple variables, arrays, labels, switches, and procedures. The scope of a quantity is the set of statements and expressions in which the declaration of the identifier associated with that quantity is valid. C (2007)WG14 N1256 (2007 updated version of the C99 standard), 6.2.1 Scopes of identifiers, 2007-09-07 An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter. The same identifier can denote different entities at different points in the program. [...] For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Go (2013)The Go Programming Language Specification: Declarations and scope, Version of Nov 13, 2013 A declaration binds a non-blank identifier to a constant, type, variable, function, label, or package. [...] The scope of a declared identifier is the extent of source text in which the identifier denotes the specified constant, type, variable, function, label, or package.
Most commonly "scope" refers to when a given name can refer to a given variable—when a declaration has effect—but can also apply to other entities, such as functions, types, classes, labels, constants, and enumerations.
Lexical scope vs. dynamic scope A fundamental distinction in scope is what "part of a program" means. In languages with lexical scope (also called static scope), name resolution depends on the location in the source code and the lexical context (also called static context), which is defined by where the named variable or function is defined. In contrast, in languages with dynamic scope, the name resolution depends upon the program state when the name is encountered which is determined by the execution context (also called runtime context, calling context or dynamic context). In practice, with lexical scope a name is resolved by searching the local lexical context, then if that fails, by searching the outer lexical context, and so on; whereas with dynamic scope, a name is resolved by searching the local execution context, then if that fails, by searching the outer execution context, and so on, progressing up the call stack.
Most modern languages use lexical scope for variables and functions, though dynamic scope is used in some languages, notably some dialects of Lisp, some "scripting" languages, and some template languages. Perl 5 offers both lexical and dynamic scope. Functions that use lexically scoped variables are known as closures.
Lexical resolution can be determined at compile time, and is also known as early binding, while dynamic resolution can in general only be determined at run time, and thus is known as late binding.
Related concepts In object-oriented programming, dynamic dispatch selects an object method at runtime, though whether the actual name binding is done at compile time or run time depends on the language. De facto dynamic scope is common in macro languages, which do not directly do name resolution, but instead expand in place.
Some programming frameworks like AngularJS use syntactically the term "scope" to mean — the semantics of word — something entirely different than how it is used in this article. In those frameworks, the scope is just an object of the programming language that they use (JavaScript in case of AngularJS) that is used in certain ways by the framework to emulate dynamic scope in a language that uses lexical scope for its variables. Those AngularJS scopes can themselves be in context or not in context (using the usual meaning of the term) in any given part of the program, following the usual rules of variable scope of the language like any other object, and using their own inheritance and transclusion rules. In the context of AngularJS, sometimes the term "$scope" (with a dollar sign) is used to avoid confusion, but using the dollar sign in variable names is often discouraged by the style guides.
Use Scope is an important component of name resolution, which is in turn fundamental to language semantics. Name resolution (including scope) varies between programming languages, and within a programming language, varies by type of entity; the rules for scope are called scope rules (or scoping rules). Together with namespaces, scope rules are crucial in modular programming, so a change in one part of the program does not break an unrelated part.
Overview
When discussing scope, there are three basic concepts: scope, extent, and context. "Scope" and "context" in particular are frequently confused: scope is a property of a name binding, while context is a property of a part of a program, that is either a portion of source code (lexical context or static context) or a portion of run time (execution context, runtime context, calling context or dynamic context). Execution context consists of lexical context (at the current execution point) plus additional runtime state such as the call stack. Strictly speaking, during execution a program enters and exits various name bindings' scopes, and at a point in execution name bindings are "in context" or "not in context", hence name bindings "come into context" or "go out of context" as the program execution enters or exits the scope. However, in practice usage is much looser.
Scope is a source-code level concept, and a property of name bindings, particularly variable or function name bindings—names in the source code are references to entities in the program—and is part of the behavior of a compiler or interpreter of a language. As such, issues of scope are similar to pointers, which are a type of reference used in programs more generally. Using the value of a variable when the name is in context but the variable is uninitialized is analogous to dereferencing (accessing the value of) a wild pointer, as it is undefined. However, as variables are not destroyed until they go out of context, the analog of a dangling pointer does not exist.
For entities such as variables, scope is a subset of lifetime (also known as extent)—a name can only refer to a variable that exists (possibly with undefined value), but variables that exist are not necessarily visible: a variable may exist but be inaccessible (the value is stored but not referred to within a given context), or accessible but not via the given name, in which case it is not in context (the program is "out of the scope of the name"). In other cases "lifetime" is irrelevant—a label (named position in the source code) has lifetime identical with the program (for statically compiled languages), but may be in context or not at a given point in the program, and likewise for static variables—a static global variable is in context for the entire program, while a static local variable is only in context within a function or other local context, but both have lifetime of the entire run of the program.
Determining which entity a name refers to is known as name resolution or name binding (particularly in object-oriented programming), and varies between languages. Given a name, the language (properly, the compiler or interpreter) checks all entities that are in context for matches; in case of ambiguity (two entities with the same name, such as a global and local variable with the same name), the name resolution rules are used to distinguish them. Most frequently, name resolution relies on an "inner-to-outer context" rule, such as the Python LEGB (Local, Enclosing, Global, Built-in) rule: names implicitly resolve to the narrowest relevant context. In some cases name resolution can be explicitly specified, such as by the global and nonlocal keywords in Python; in other cases the default rules cannot be overridden.
When two identical names are in context at the same time, referring to different entities, one says that name masking is occurring, where the higher-priority name (usually innermost) is "masking" the lower-priority name. At the level of variables, this is known as variable shadowing. Due to the potential for logic errors from masking, some languages disallow or discourage masking, raising an error or warning at compile time or run time.
Various programming languages have various different scope rules for different kinds of declarations and names. Such scope rules have a large effect on language semantics and, consequently, on the behavior and correctness of programs. In languages like C++, accessing an unbound variable does not have well-defined semantics and may result in undefined behavior, similar to referring to a dangling pointer; and declarations or names used outside their scope will generate syntax errors.
Scopes are frequently tied to other language constructs and determined implicitly, but many languages also offer constructs specifically for controlling scope.
Levels of scope