Many languages (for example Pascal) are very restrictive on
the declaring of variables of a specific type from two different
parts of a program. E.g:
var // GLOBAL DECLARATION.
x:array [1..35] of integer;
:
procedure xxxxxx
var // LOCAL DECLARATION.
y:array [1..35] of integer;
Even worse is the following:
var // GLOBAL DECLARATION.
x:array [1..35] of integer;
y:array [1..35] of integer;
type fish=array [1..35] of integer;
var x:fish;
y:fish;
or
var x,y:array [1..35] of integer;
Why? This is because the compiler must determine if the variables are of a compatible type. When it is processing the variable declarations, it creates symbol table information about the type of the variable, puts it into a record and then points the variable's "what is my type" pointer to the record. When it checks for compatibility, it simply checks to see if the two pointers are the same not if they point to things which are the same. Variables declared in the same declaration or with the same simple type, will have identical pointers. Variables declared in different declarations will have different pointers (even though they may point to records which are the same). This is the difference between name equivalence and structure equivalence.
It is often more convenient to produce a new type (in this case type fish) in case other variables or, more importantly, procedure parameters are of that type.
In some languages, it is illegal to declare a procedure as
follows:
procedure sss(a:array[1..5] of ...);
procedure sss(a:fish);