b) Checking Behaviour

It is a common belief that behaviour conformance is not statically checkable. Let's demonstrate the contrary on a detail of the hopefully familiar example of the dining philosophers ([Hoare85]):

Philosophers are sitting around a table, eating spaghetti. A philosopher is defined by his ability to take a pair of forks, eat, and place the forks back on the table (there is just as many forks as there are philosophers). The detail, we choose to focus on, is how to statically ensure that users of the philosopher type cannot attempt to have them pick up forks twice in a row, or put them back on the table before they have first taken them. A simple answer using C++ concepts is to offer one only public member function, "eat", in a philosopher abstract class, and define it in this class to call in sequence three virtual protected members, "take_forks", "eat_" and "put_forks".

This simple technique shows a (trivial) behaviour specification: the key point here is that the code, defined in the abstract class, is itself part of the interface, not of the yet undefined implementation of the philosophers. This technique can be extended to support protocols of significant complexity by resorting to dedicated interfaces (e.g. in C++, through friendship):

Let's now suppose that instead of the former requirement, we would have had to consider the situation from the point of view of fork pairs (to keep it simpler): two members, "take" and "put" and the same constraints. We would have made these virtual members protected, and designed an abstract "eater" class as a "friend". This one would have only differed from the formerly sketched "philosopher" in that it would have delegated the reclaiming and disposing of the forks to external resources. This would have constrained new "philosophers" to specialize our "eater" class, making this one, in fact, the "fork_pair"'s interface.

We acknowledge that we are not yet even on the way to solve Hoare's initial puzzle. This is however sufficient for our purpose. This kind of design is such uncommon that e.g. [BR95] sacrifices it in C++, [Vinoski93] in IDL, in favour of a weaker signature compatibility. Signature is the term coined by [BR95]. It is extrapolated from the concept of function signature: the name of the function, decorated with the type of its input parameters for linking purposes. This is a key element in the way static typing has traditionally been implemented e.g. in C. A class's signature is the set of all the signatures of its public member functions. Vinoski uses the term behaviour for a very similar concept in IDL, stressing with this choice the fact that IDL interfaces do not describe any data. We reserve behaviour (following [WZ88]) for the service expected by a client from a type, expressed at least conceptually through relationships between the pre- and post-conditions of the class members. From a classical example, a square and a cowboy may have the same signature, if they have only one member, draw. They have yet different behaviours.

Table of contents


Marc Girod
Last modified: Sat Feb 28 14:23:20 EET 1998