[Next] [Previous] [Up] [Top] [Contents] [Index]

3.6 Type Checking Messages

3.6.1 Checking Messages Against Signatures

Given a message of the form name(expr1,...,exprN), where each expri type-checks and has static type Ti, the type checker uses the Ti to locate all signatures of the form name(S1,...,SN):SR where each type Si is a supertype of the corresponding Ti. If this set of applicable signatures is empty, the checker reports a "message not understood" error. Otherwise, the message send is considered type-correct.

To determine the type of the result of the message send, the type system calculates the most-specific result type of any applicable signature. This most-specific result type is computed as the greatest lower bound of the result types of all applicable signatures. In the absence of other type errors, this greatest lower bound will normally correspond to the result type of the most-specific signature.

To illustrate, consider the message copy(some_list), where the static type of some_list is list. The following types and signatures are assumed to exist:

type collection;
type list subtypes collection;
type array subtypes collection;

signature copy(collection):collection;
signature copy(list):list;
signature copy(array):array;

The signature copy(array):array is not applicable, since list, the static type of some_list, is not a subtype of array. The dynamic type of some_list might turn out to conform to array at run-time (e.g., if there were some data structure that was both a list and an array), but the static checker cannot assume this and so must ignore that signature. The first two signatures do apply, so the copy message is considered legal. The type of the result is known to be both a list and a collection. The greatest lower bound of these two is list, so the result of the copy message is of type list.

Unlike method dispatching, it is acceptable for more than one signature to be applicable to a message. Signatures are contracts that clients can assume, and if more than one signature is applicable, then the client can assume more guarantees about the type of the result. The greatest lower bound is used to calculate the message's result type, rather than the least upper bound, because each signature can be assumed to be in force. At run-time, a method will be selected, and that method will be required to honor the result type guarantees of all the applicable signatures, and so the target method implementation will return an object that conforms to the result types of all the applicable signatures, i.e., the greatest lower bound of these signatures. In common practice, some most-specific signature's result type will be the greatest lower bound, such as the list type selected above.