Don't underrate Dennis Ritchie. Every statically typed language should have a way to create an abstract type which it is impossible for a user to forge. For this you need a type construct or declaration construct that is generative, i.e., every instance of the construct generates a fresh type, distinct from any other. Such a construct is vital if you want to keep other people's mitts off your data. (For plenty of examples, see Dave Hanson's book C Interfaces and Implementations.)
So here values p1
and p2
have different types but the same representation:
struct { float x, y } p1;
struct { float x, y } p2;
Why pick struct
to be generative? Because it's general enough to allow a wide range of convenient representations. union
is a bit of a stretch, but I suspect it's "collateral design"; in C's type system, union
behaves as much list struct
as possible, which simplifies the compiler.
Incidentally, "declaration equivalence" is a term I have never heard before. 25 years ago terms like "name equivalence", "structural equivalence", and "occurence equivalence" were popular. Today type systems are much more formal, and equivalence is typically defined by logical rules rather than informal English. When it is helpful to resort to informal English, I usually find that the idea of "generativity" has more explanatory power than inventing a new name for the equivalence rules of each new language.