Type definitions are provided both for convenience of making programs more legible by giving ``logical'' names (or terms) to otherwise verbose types, and that of hiding information details of a type making it act as a new type altogether. The former facility is that of providing aliases to types (exactly like a preprocessor's macros get expanded right away into they textual equivalents), while the latter offers the convenience of defining new types in terms of existing ones, but hiding this information. In particular, a type alias is always structurally equivalent to its value (in fact an alias disappears right way being replaced by the structure defining it). By contract, a defined type is never structurally equivalent to its value nor any other type--it is only equivalent to itself. To enable meaningful computation with a defined type, two meta-(de/con)structors are thus provided: one for explicitly casting a defined type into the type that defines it, and one explicitly seeing a type as a specified defined type (if such a defined type does exist and with this type as definition).
The class ilog.language.design.types.Tables contains the symbol tables for global names and types. The name spaces of the identifiers denoting type and non-type (global or local) names (which are kept in the global symbol table) are disjoint--so there are no name conflicts between types and non-type identifiers.
The typeTable variable contains the naming table for types and the symbolTable variable contains the naming table for other (non-type) global names.
This section will unfold all the type-related data-structures starting from the class that manages symbols: ilog.language.design.types.Tables. The names can be those of types and values. They are global names.4.4 The type namespace is independent of the value namespace--i.e., the same name can denote a value and a type.