Suppose we have a function with type Func(S): T. In order
to use an element,
, of type
in place of
, the function
must be able to accept an
argument of type
and return a value of type
. See Figure
2. But
is defined to
accept arguments of type
. Now
can be applied to
an argument,
, of type
if
.
In that case, using subsumption,
can be treated as an element of
type
, making
typable. Similarly, if the output of
has type
then
will guarantee that
the output can be treated as an element of type
. Summarizing,
Again assuming that , we get that
Procedure types, written , may be subtyped as though they
were degenerate function types that always return a default type
, which has only a single value. Thus
Notice that the ordering of parameter types in function and procedure subtyping is the reverse of what might initially have been expected, while the output types of functions are ordered in the expected way. We say that subtyping for parameter types is contravariant (i.e., goes the opposite direction of the relation being proved) while the subtyping for result types of functions is covariant (i.e., goes in the same direction). The contravariance for parameter types can be initially confusing, because it is permissible to replace an actual parameter by another whose type is a subtype of the original. However the key is that in the subtyping rule for function types it is the function, not the actual parameter, which is being replaced.