posted 14 years ago
This is a page from "Fundamentalks of Object oriented languages". Anyone please explain what is said in the last paragraph of the text.
Function types
The proper definition of subtyping for function types has provoked great
controversy and confusion, so it is worth a careful look. As discussed earlier,
we write ST for the type of functions that take a parameter of type S and
return a result of type T. If (S’ T’) (S T), then we should be able to
use an element of the first functional type in any context in which an element
of the second type would type check.
Suppose we have a function f with type ST. In order to use a function,
f’, with type S’ T’, in place of f, the function f’ must be able to accept
an argument of type S and return a value of type T. See Figure 5.2.
To masquerade successfully as a function of type ST, function f’ must
be able to be applied to an argument, s, of type S. Because the domain of
f’ is S’, it can be applied to elements of type S as long as S S’. In that
case, using subsumption, s can be treated as an element of type S’, making
f’(s) type-correct.
On the other hand, if the output of f’ has type T’, then T’ T will
guarantee that the output of f’ can be treated as an element of type T. Summarizing,
S’ T’ S T if S S’ and T’ T
If we assume, as before, that CheeseType FoodType, it follows that
(Integer -> CheeseType) (Integer -> FoodType)
but
(FoodType -> Integer) (CheeseType -> Integer)
In the latter case, if f’: FoodType Integer, then f’ can be applied to
an expression of type CheeseType, since that expression can masquerade
as being of type FoodType.
The reverse is not true, since if f: CheeseTypeInteger, it may not be
possible to apply f to an argument of type FoodType. The body of f may
apply an operation that is only defined for expressions of type CheeseType.
For example, suppose melt is a function that can be applied to elements of
type CheeseType, but not FoodType. Thenif melt is applied to the parameter
in the body of f, an execution error would arise if the actual parameter
was of type FoodType and not CheeseType.
Procedure types may be subtyped as though they were degenerate function
types that always return a default type Void.
The subtype ordering of parameter types in function 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 always 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.
Let us look at one last example to illustrate why contravariance is appropriate
for type changes in the parameter position of functions and procedures.
The contravariant rule for procedures tells us that it is possible to
replace a procedure, p, of type CheeseTypeVoid by a procedure, p’, of
type FoodTypeVoid.
The procedure p can be applied to any value, cheese, of type Cheese-
Type. Because CheeseType FoodType, the value cheese can masquerade
as an element of type FoodType. As a result, p’ can also be applied
to the value cheese. Thus p’, and indeed any procedure of type FoodType
Void, can masquerade as an element of type CheeseTypeVoid.
MadhanBabu B
Coimbatore
India