74 Comparable Types

Definition (disjoint):
Types A and B are disjoint if they are comparable and their carrier sets are disjoint.

Definition (incomparable):
Types A and B are incomparable if equality between them is undefined and any attempt to compare them, implicitly or explicitly, produces a type error.

Definition (comparable):
Two types A and B are comparable iff they share a unique least common supertype T with defined equality. If multiple candidate supertypes exist and none is a subtype of the others, A and B are incomparable.

In the following example, types B and C have a unique least common supertype A, but A is abstract and therefore does not define equality. B and C also have a non-empty common subtype D. Nevertheless, B and C are incomparable. This is based on static typing: attempting to compare expressions of static types B and C produces a type error, even if the expressions denote values lying in the common subtype D.


abstract value A {};
value B { Integer x; };
value C { Integer x; };
value D { Integer x; };
B,C isa A;
// D isa B,C;
B(D:d) { x = d.x; }
C(D:d) { x = d.x; }
var b = B { x=1 };
var c = C { x=1 };
print b = c;        // type error:  B and C are incomparable

Declaring disjointness for B and C, and naming their union type, records that their carrier sets do not overlap. This makes cross-member equality available as false:


value B { Integer x; };
value C { Integer x; };
disjoint B, C;
type A = union { B, C };
var b = B { x=1 };
var c = C { x=1 };
print b = c;        // prints false

Naming the same union type multiple times does not create distinct supertypes.


value B { Integer x; };
value C { Integer x; };
disjoint B, C;
type A1 = union { B, C };
type A2 = union { B, C };
var b = B { x=1 };
var c = C { x=1 };
print b = c;        // prints false