Cforall Type System
Cforall type system is based on parametric polymorphism, the ability to declare functions with type parameters, rather than an object-oriented type system.
This required four groups of extensions.
- Overloading
-
Function, data, and operator identifiers may be overloaded.
`
a + b' is equivalent to `?+?(a, b)', where
`?+?' is the name of the addition function. The standard
prelude `declares' the standard C operators. The overload resolution
algorithm mimics C's implicit conversions.
- Type declarations
-
The declaration `type T;' states that T is a type identifier. Its
value could be any of C's object types. (Similarly,
`
dtype' is used for object and incomplete types, and
`ftype' is used for function types.) Type declarations with
initializers provide definitions of new types. Type declarations
with storage class `extern' provide opaque types.
- Polymorphic functions
-
A
forall clause declares a type parameter. The
corresponding argument is inferred at the call site.
forall(type T)
void swap(T left, T right) {
T temp = left; /* Note instantiation of T */
left = right;
right = temp;
}
int a = 1, b = 2;
swap(a, b); /* T inferred to be int */
swap is not a template; it is a real function,
with an address and a type.
- Specifications and assertions
-
Specifications are collections of declarations parameterized by one
or more types. They serve many of the purposes of abstract
classes, and specification hierarchies resemble subclass hierarchies.
Unlike classes, they can define relationships between types.
/* Points along a dimension, and distances between them. */
spec dimension(type Pt, type Delta) {
Pt ?+?(Pt, Delta);
Pt ?+?(Delta, Pt);
Delta ?-?(Pt, Pt);
Pt ?-?(Pt, Delta);
};
Assertions declare that a type or types provide the operations
declared by a specification. `dimension(char*,
ptrdiff_t)' announces that the types char* and
ptrdiff_t are related by (pointer) arithmetic operations.
Assertions are normally used to declare requirements on type arguments
of polymorphic functions.
Here is a small example of all four extensions together:
/* Object types with a `+' operator */
spec addable(type T) {
T ?+?(T, T);
};
/* Double a value of any type that has a `+' operator */
forall(type T | addable(T))
T double(T opnd) {
return opnd + opnd;
}
/* A type whose implementation is unknown, but is known to
have an addition operator. */
extern type Complex | addable(Complex);
Complex c;
...
c = double(c);