Jump to content

Name binding

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 76.212.129.202 (talk) at 04:50, 12 September 2008 (Update late static binding example to reference latest versions of PHP). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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.

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.

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 initially 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.

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" (possibly available beginning with PHP 5.3) in A::hello()

class A {
  static $word = "Welcome";
  static function hello() {print static::$word;}
}

class B extends A{
  static $word = "bye";
}

B::hello();

See also