overloading and polymorphism ... see Miranda notes
A : array(1 .. 10) of BOOLEAN; B : array(1 .. 10) of BOOLEAN; C, D : array(1 .. 10) of BOOLEAN;Ada defines A and B as of different types, but C and D are both of the same type. Here's another example, with some type declarations:
type VEC is array(1 .. 10) of INTEGER;
type VEC2 is array(1 .. 10) of INTEGER;
A : VEC;
B, C : VEC;
D : VEC2;
type PERSON is
record
NAME : STRING(1 .. 120);
POUNDS : INTEGER;
end record;
type ENGLISH_ACCOUNT_PAYABLE is
record
NAME : STRING(1 .. 120);
POUNDS : INTEGER;
end record;
subtype SMALL_INT is INTEGER range -10 .. 10;
I : INTEGER;
J : SMALL_INT;
Here A, B, and C are all of the same type; D is of a different type.
PERSON and ENGLISH_ACCOUNT_PAYABLE are different types. This is all consistent
with pure name equivalence.
I and J are both integers. (In pure name equivalence they would be different
-- this is the "modified" part.)
The structural equvalence rule in its pure form would say that A, B, C, and D are all of the same type, and PERSON and ENGLISH_ACCOUNT_PAYABLE are the same type. Algol-68 is an example of a language that uses structural equivalence. This kind of structural equivalence has pretty much fallen out of favor though.
C would say that A, B, C, and D are all of the same type, and PERSON and ENGLISH_ACCOUNT_PAYABLE are different types. C uses structural equivalence, except for records (structs).
Variant records -- are they done in a type safe way? Pascal: no. Ada: yes. In Ada, a variant record must have a discriminant that lets the compiler distinguish between the cases; the discriminant must be set at the same time as the variant fields.
type DEVICE is (PRINTER, FLOPPY, HARD_DISK);
type STATE is (UP, DOWN);
type PERIPHERAL(UNIT : DEVICE := PRINTER) is
record
STATUS: STATE;
case UNIT is
when PRINTER => PAGE_LENGTH : FLOAT;
when others => MEGABYTES : INTEGER;
end case;
end record;
P : PERIPHERAL;
P := (UNIT => FLOPPY, MEGABYTES => 2);
-- not allowed: P.unit := printer;