In languages with dynamic data typing, such as Self, Smalltalk and many scripting languages, the data types are not declared. They are determined at execution time. Dynamic typing often occurs in scripting languages and other rapid application development languages. Dynamic type tags appear more often in interpreted languages, whereas compiled languages favor static types without run-time tags.
The advantage of dynamic data typing is more flexibility and less work for the programmer. But often the data type declarations help in organizing and understanding a program. A programming language is dynamically typed if the language supports run-time (dynamic) dispatch on tagged data. A programming language is dependently typed, if the phase distinction is violated and consequently the type checking requires testing equivalence of run-time expressions.
In dynamic typing, type tag checking often takes place at runtime because values bound in variables can acquire different tags depending on the execution path. Type tags are represented using discriminated union types in statically typed programming languages.
To see how type tag checking works, consider the following pseudo code example:
var x; // (1) x := 5; // (2) x := "hi"; // (3)
In this example, (1) declares the name x; (2) associates the integer value 5 to the name x; and (3) associates the string value "hi" to the name x. In most statically typed systems, this code fragment would be illegal, because (2) and (3) bind x to values of inconsistent type.
By contrast, a purely dynamically typed system would permit the above program to execute, since type tags are attached to values, not variables. The implementation of a dynamically typed language catches programmer errors related to the misuse of values - type errors - at the time of the computation of the erroneous statement or expression. In other words, dynamic typing catches errors during program execution.
A typical implementation of dynamic typing keeps all program values "tagged" with a type tag, and checks the tag before using any value in an operation. For example:
var x := 5; // (1) var y := "hi"; // (2) var z := x + y; // (3)
In this code fragment, (1) binds the value 5 to x; (2) binds the value "hi" to y; and (3) attempts to add x to y. In a dynamically typed language, the value bound to x might be a pair (integer, 5), and the value bound to y might be a pair (string, "hi"). When the program attempts to execute line 3, the language implementation checks the type tags integer and string, and if the operation + (addition) is not defined over these two types it signals an error.