next up previous contents
Next: Replacing subtyping with matching Up: Solutions to Eiffel's covariant Previous: Solving covariance problems with

Meyer's solution: Banning polymorphic catcalls

  Bertrand Meyer, the designer of Eiffel, has rejected this sort of solution to the covariance typing problems in Eiffel, because it requires the programmer to plan ahead in order to accommodate subclasses. That is, the designer of the ${\it {Animal}}$ class must know in advance to make the class polymorphic in the food type or the class representing herbivores will not be definable as a subclass.

In the fall of 1995, Meyer [Mey95] proposed a different solution to the covariance typing problems. His solution was to identify and ban what he called polymorphic catcalls . While this notion is too complex to be defined here, this proposal was intended to bar particular kinds of message sends to objects whose type was not known exactly.

To illustrate how this proposal would preserve type safety, let us return to our example ${\it {breakit}}$ procedure in Figure 13 which shows that subclasses need not be subtypes. In that example the message ${\it {attachRight(n2)}}$ was sent to ${\it {n1}}$, where ${\it {n1}}$ was a parameter declared to have type ${\it {NodeType}}$. The problem arose when the actual parameter corresponding to ${\it {n1}}$ actually had type ${\it {DoubleNodeType}}$. We avoided this problem by not allowing ${\it {DoubleNodeType}}$ to be a subtype of ${\it {NodeType}}$ since ${\it {attachRight}}$ was a binary method.

Meyer's new proposal would avoid the problem as follows. He would label ${\it {n1.attachRight(n2)}}$ a catcall since the type of the formal parameter of ${\it {attachRight}}$ is changed in a covariant way in a subclass of ${\it {Node}}$. The receiver ${\it {n1}}$ would be termed polymorphic since the exact type of its value is unknown. This follows since it is a formal parameter and hence any element of a subclass of ${\it {Node}}$ may be used as a parameter. Hence the entire expression is considered a polymorphic catcall and hence is illegal.

An interesting part of the definition is that the original expression would not be considered a catcall until a subclass of ${\it {Node}}$ is declared. Thus the procedure ${\it {breakit}}$ would be legal in an Eiffel program unless and until a subclass is defined. Meyer argues that an incremental compiler could determine this change in status at no great cost.

Thus in the solution proposed earlier in this paper, the procedure ${\it {breakit}}$ is legal, but it may only be applied to parameters of type ${\it {NodeType}}$ (since ${\it {NodeType}}$ has no subtypes). We could also use match-bounded polymorphism to rewrite the procedure as in Figure 21. This is still type safe, but is more flexible in that it would allow calls of the form ${\it {nobreakit(SomeNodeType,nd1,nd2)}}$ as long as ${\it {nd1}}$ and ${\it {nd2}}$both have type ${\it {SomeNodeType}}$. In particular it could be called with ${\it {DoubleNodeType}}$ and two actual parameters of type ${\it {DoubleNodeType}}$.


  
Figure 21: A type safe rewrite of ${\it {breakit}}$ using match-bounded polymorphism.
\begin{figure*}
\begin{verbatim}
procedure nobreakit(T < ...

In Meyer's proposal, the original ${\it {breakit}}$ would be legal only as long as ${\it {Node}}$ had no subclasses. When the first subclass was defined, the procedure would become illegal and have to be rewritten or eliminated.

We have several concerns with Meyer's new proposal.

1.
The definition of polymorphic catcall (and related restrictions) is very complex, and would be difficult for most programmers to understand in detail.
2.
We are not completely confident that this proposal will actually solve all of the type problems of Eiffel. The original proposal did not take care of some problems arising from changes to instance variables in subclasses. While the rules have since been corrected, the complexity of the rules and the lack of a proof of correctness leaves room for doubt.
3.
The proposal may be too conservative. A receiver of a message is polymorphic if it can evaluate to an object of more than one class. In most large systems inheritance is used a great deal, and this may lead to a large number of polymorphic expressions to which catcalls may not be sent.

Only experience with these rules will determine whether or not there is any validity to these concerns. Meanwhile, the type system discussed in this paper provides an alternative solution to the covariant typing problems of Eiffel, albeit one that requires the programmer to plan ahead.


next up previous contents
Next: Replacing subtyping with matching Up: Solutions to Eiffel's covariant Previous: Solving covariance problems with
Kim Bruce
10/28/1998