By our earlier definition, a variable is a function and the value returned by this function must be a member of the set { Undefined} where is the type of the variable. When an expression is assigned to a variable, it is thus necessary to ensure that the expression results in a member of { Undefined} before allowing the assignment to take effect.
Since operators are also functions, expressions can be regarded as function applications. The type of an expression is thus the range set of the (outer) function that is being applied. This is guaranteed to be a subset of {Undefined} where is the codomain of the function.
Now, if or , the validity of the assignment can be decided without evaluating the expression. Thus, a language designer can ensure that all type checks can be done by a compiler, simply by insisting that assignments are illegal unless .
Compile-time (or static) type checking is generally regarded as highly desirable and hence many language designers claim that their languages allow static type checking. In practice, however, static type checking is so restrictive that no realistic language enforces it. Virtually all languages allow assignments to be carried out if and generate run-time checks to ensure that the assignments are legal. The main difference from language to language is whether the language forces the programmer to make the type check explicit or not.
If types are to intersect freely, however, it is not reasonable to insist that . Assignments should be allowed, subject to run-time checks if necessary, whenever .
Of course, this means that many type errors that are easily detected by the compilers of languages like Ada and Oberon, become very difficult for a compiler to detect, thus requiring the generation of expensive run-time checks. The author contends, however, that it is no longer appropriate to restrict the expressivity of a language merely to limit the complexity of compilers and run-time systems. Such a strategy does not get rid of the complexity, it merely dumps it over the fence in the application programmer's yard. Furthermore, much progress is being made on the optimization of ``dynamic'' languages (for example [3]) and it seems reasonable to expect that such compilers will convert most run-time errors into compile-time errors.
That is, while static languages may be safer than dynamic languages at present, they are not inherently safer.
Prof Herman Venter