Type compatibility: Difference between revisions

From Rosetta Code
Content added Content deleted
(Created)
 
m (Some grammar, a link)
Line 1: Line 1:
[[Category:Encyclopedia]]'''Types equivalence''' describes the way types are considered equivalent when matched. Types can be equivalent:
[[Category:Encyclopedia]]'''Type equivalence''' describes the way types are considered equivalent when matched. Types can be equivalent:


* by name (nominal equivalence);
* by name (nominal equivalence);
* by structure (structural equivalence).
* by structure (structural equivalence).


In a more general context types matching considers not only the relation of types equivalence (T<sub>1</sub>=T<sub>2</sub>), but also the relations of subsumption (T<sub>1</sub><:T<sub>2</sub>), subtyping, subclassing etc. These also can be nominal or structural.
In a more general context type matching considers not only the relation of type equivalence (T<sub>1</sub>=T<sub>2</sub>), but also the relations of subsumption (T<sub>1</sub><:T<sub>2</sub>), subtyping, [[inheritance|subclassing]] etc. These also can be nominal or structural.


A structural matching is necessarily based on types inference. In presence of user-defined abstract data types it is in general case undecidable whether two types are semantically equivalent to each other. Even if equivalence is decidable, in complicated cases it might be very difficult for the code maintainer to determine if two types in question are indeed equivalent or not. It is also incompatible with the ''information hiding principle'', because hidden implementation details might prevent the reader to see types equivalent. For these reasons modern typed languages with elaborated types systems tend to nominal types equivalence. At the same time for many standard types and especially for subtypes it becomes very tedious to use nominal equivalence. Therefore programming languages have some pragmatic mixture of structural and nominal equivalences.
A structural matching is necessarily based on type inference. In presence of user-defined abstract data types, it is generally undecidable whether two types are semantically equivalent to each other. Even if equivalence is decidable, in complicated cases it might be very difficult for the code maintainer to determine if two types in question are indeed equivalent or not. It is also incompatible with the ''information hiding principle'', because hidden implementation details might prevent the reader to see types equivalent. For these reasons modern typed languages with elaborated type systems tend towards nominal type equivalence. At the same time for many standard types, and especially for subtypes, it becomes very tedious to use nominal equivalence. Therefore, programming languages have some pragmatic mixture of structural and nominal equivalences.
==Nominal equivalence example (in [[Ada]])==
==Nominal equivalence example (in [[Ada]])==
<ada>
<ada>
Line 21: Line 21:
Y : not null access String := X; -- This is OK
Y : not null access String := X; -- This is OK
</ada>
</ada>
The anonymous type of X matches the anonymous type of Y. The structure of both types is same: "a pointer to String". Further the constraint ''not null'' put on the type of Y does not effect equivalence because it is also structural.
The anonymous type of X matches the anonymous type of Y. The structure of both types is the same: "a pointer to String". Further, the constraint ''not null'' put on the type of Y does not effect equivalence because it is also structural.

Revision as of 19:02, 25 July 2008

Type equivalence describes the way types are considered equivalent when matched. Types can be equivalent:

  • by name (nominal equivalence);
  • by structure (structural equivalence).

In a more general context type matching considers not only the relation of type equivalence (T1=T2), but also the relations of subsumption (T1<:T2), subtyping, subclassing etc. These also can be nominal or structural.

A structural matching is necessarily based on type inference. In presence of user-defined abstract data types, it is generally undecidable whether two types are semantically equivalent to each other. Even if equivalence is decidable, in complicated cases it might be very difficult for the code maintainer to determine if two types in question are indeed equivalent or not. It is also incompatible with the information hiding principle, because hidden implementation details might prevent the reader to see types equivalent. For these reasons modern typed languages with elaborated type systems tend towards nominal type equivalence. At the same time for many standard types, and especially for subtypes, it becomes very tedious to use nominal equivalence. Therefore, programming languages have some pragmatic mixture of structural and nominal equivalences.

Nominal equivalence example (in Ada)

<ada> type Integer_1 is range 1..20; type Integer_2 is range 1..20;

X : Integer_1 := 1; Y : Integer_2 := X; -- Type error </ada> Integer_1 does not match Integer_2 though both types have equivalent sets of values and operations.

Structural equivalence example (in Ada)

<ada> X : access String := new String'("ABC"); Y : not null access String := X; -- This is OK </ada> The anonymous type of X matches the anonymous type of Y. The structure of both types is the same: "a pointer to String". Further, the constraint not null put on the type of Y does not effect equivalence because it is also structural.