Metaclass, and the Dogs of Shakespeare
In my February column on poly morphism I explained why little Dogs go "woof woof" and bigDogs go "Woof Woof Woof Woof" (OS/2 Magazine, p. 46). Implicit in this discussion was that all dogs bark when asked, and the only difference between the types of dogs is the nature of that bark. I showed how the code:
_bark(Lassie, ev)
generates the bigDog bark ("Woof Woof Woof Woof"), while the code:
_bark(Toto,ev)
generates the littleDog bark ("woof woof").
However, I was recently reading Shakespeare, and it occurred to me that I made an error in that column. I believe in admitting my mistakes, so here is an attempt to set the record straight.
The line that made me rethink my analysis of littleDogs was this line, spoken by King Lear: "The little dogs and all, Tray, Blanch, and Sweet-heart, see, they bark at me." In order to see why this line caused me such vexation, we must translate it from Shakespearean English into a more familiar language, namely SOM with the C bindings. The SOM C translation of it is:
King KingLear; LittleDog Tray,Blanch,Sweetheart; /* ... */ _enter(KingLear, ev); _LookAt(Tray,ev); _LookAt(Blanch,ev); _LookAt(Sweetheart, ev);
resulting in the following output:
woof woof woof woof woof woof
The problem is that at no point does King Lear ask any of the littleDogs to bark! This act is quite at odds with the code I showed in February, which would have permitted the littleDogs to bark only if their monarch so requested. With my polymorphic littleDogs, Shakespeare would have had to include these lines in his play to get his desired effect:
_bark(Tray, ev); _bark(Blanch,ev); _bark(Sweetheart, ev);
So, in this column I am going to reimplement littleDogs as they would have been programmed by the Bard himself.
Let's analyze the situation further. Just what did King Lear do to make the dogs bark? Perhaps he looked at the dogs? I believe Shakespeare's intention was that looking at the dogs was merely one example of what King Lear might have done to set off the barking fit. I submit that anything King Lear did to the dogs would have had the same result. They would have barked even if King Lear had asked them to roll over!"
In other words, these dogs always bark, in addition to doing whatever it is they do. Barking, then,is not associated with the implementation of a method, but rather is associated with the invocation of a method. How do we program this in SOM?
The answer is to slip into a new mode of programming, one that Ira Forman describes as metaclass programming. Ira is one of the SOM developers and great champions of metaclass programming, which he describes as the next major advance in programming languages. As you can see, Ira, similar to all great champions, sometimes gets carried away, but he does raise some interesting issues. I, along with many others, am indebted to him for first explaining the concepts of metaclass programming.
Those of YO)I who have heard Ira's talks will recognize my reimplemented barking dogs as an adaptation of Ira's growling dogs example (which, of course, is an adaptation of my original barking dog, so all's fair).
We can briefly describe metaclass programming as programming not at the object level, but at the class level. It turns out that we are still programming objects, but these are now very special objects-class objects. Lets look more closely at these class objects.
All SOM objects are associated with some class. Knowing that Toto, for example, is instantiated as a littleDog tells us that the Toto object is associated with the littleDog class.
Every class that is available to a given SOM program has an associated object called the class object. If littleDog is derived from dog, and dog from SOMObject (the root of all SOM objects), then a program with instantiated littleDogs will have class objects in its address space for SOMObject, dog, and littleDog.
These class objects are similar to other SOM objects. They must be instantiated, they are associated with a class, they are defined by IDL, and they have associated methods. Many SOM programmers aren't aware of these class objects, because they are often automatically instantiated. When one executes the statement:
Toto= LittleDogNew();