Name binding
From Wikipedia, the free encyclopedia
In programming languages, name binding is the association of values with identifiers. An identifier bound to a value is said to reference that value. Since computers themselves have no notion of identifiers, there is no binding at the machine language level — name binding is an abstraction provided by programming languages. Binding is intimately connected with scoping, as scope determines when binding occurs.
Use of an identifier id
in a context that establishes a binding for id
is called a binding (or defining) occurrence. In all other occurrences (e.g., in expressions, assignments, and subprogram calls), an identifier stands for what it is bound to; such occurrences are called applied occurrences.
Contents |
[edit] Binding time
The binding of names before the program is run is called static (also "early"); bindings performed as the program runs are dynamic (also "late" or "virtual").
An example of a static binding is a direct C function call: the function referenced by the identifier cannot change at runtime. An example of dynamic binding is dynamic dispatch, as in a C++ virtual method call. Since the specific type of a polymorphic object is not known before runtime (in general), the executed function is dynamically bound. Take, for example, the following Java code:
public void foo(List<String> list) { list.add("bar"); }
Is list
a reference to a LinkedList
, an ArrayList
, or some other subtype of List
? The actual method referenced by add
is not known until runtime. In a language like C, the actual function is known.
Since compiled programs are often relocatable in memory, every memory reference is ultimately a dynamic binding. Each variable or function is referenced as an offset from a memory segment, which is not known until runtime. This is a pedantic distinction, however, as binding operates at the programming-language level and not the machine level.
[edit] Rebinding and mutation
Rebinding should not be confused with mutation — "rebinding" is a change to the referencing identifier; "mutation" is a change to the referenced value. Consider the following Java code:
LinkedList<String> list; list = new LinkedList<String>(); list.add("foo"); list = null;
The identifier list
at first references nothing (it is uninitialized); it is then rebound to reference an object (a linked list of strings). The linked list referenced by list
is then mutated, adding a string to the list. Lastly, list
is rebound to null
.
[edit] Late static
Late static binding is a variant of binding somewhere between static and dynamic binding. Consider the following PHP example:
class A { static $word = "hello"; static function hello() {print self::$word;} } class B extends A( static $word = "bye"; } B::hello();
Without late static binding, the PHP interpreter binds the function hello() to class A when the programmer is clearly expressing the function on class B. The absence of late static binding would cause "hello" to be printed, not "bye" despite hello() being called on class B.
Late static binding in the interpreter means that $word is determined at runtime. In this case it would reference B::$word if B::hello() is called and A::$word if A::hello() is called. This does require a change in keywords from "self" to "static" in A::hello()
class A { static $word = "hello"; static function hello() {print static::$word;} } class B extends A( static $word = "bye"; } B::hello();