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
butProcedure 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.