Our next example is one in which it would be convenient to change both return types and parameter types of methods. The particular typing problem arises in connection with what are often called binary methods. Binary methods are those methods that have a parameter whose type is intended to be the same as the receiver of the message. Functions reflecting orders, such as , , and ,or other familiar binary operations or relations are good examples of such methods. These are written with single parameters in object-oriented languages because the receiver of the message plays the role of the other parameter. Other compelling examples arise in constructing linked structures. Binary methods are notoriously difficult to deal with in statically-typed object-oriented programming languages. See [BCC+96] for an extended discussion of typing problems with binary methods.
Figure 7 is a sample class definition to implement nodes for a singly-linked list. In the class there is one instance variable for the value stored in the node and another to indicate the successor node. There are methods to get and set the values stored in the node, and to get and set the successor of the node.
Notice that function returns a value of type , the type of object generated by class , while the procedures and each take a parameter of type . The method currently just sends the message to self, its use will become more apparent in section 5 when it is modified in a subclass.
Suppose we now wish to define a subclass of , , which implements doubly-linked nodes, while taking advantage of the code for methods in . To do this we need to add to an additional instance variable, , as well as new methods to retrieve and set the node. Note that if is the type of objects generated from the class, then we will want both the and instance variables to have type , and the relevant methods to take parameters or return values of type rather than .This is particularly important because we do not want to attach a singly-linked node to a doubly-linked node.
Unfortunately in the simple type system described here we have no way of changing these types, either automatically or manually, in the subclass. Thus to get the desired typings, we would have to define independently of , even though much of the code is identical. This is clearly undesirable.