![]()
The Geometry of C++ ObjectsJames O. Coplien, Bell LabsC++ Report 10(9), October 1998, pp. 40 - 44 IntroductionIn the past three installments of the Column Without a Name [Coplien1998a][Coplien1998b][Coplien1998c], I've spent a lot of time talking about Alexander's Theory of Centers. In particular, I've focused on the role geometry might play in the most beautiful, sound and functional systems we can build. Part of that focus has been on individual patterns with particularly striking geometric characteristics, and on the importance of sketches in the patterns we write. I've also discussed the importance of wholeness, a property that emerges from the geometry of a dense field of centers that combine in geometrically powerful ways. The centers of a whole system reinforce each other and complement each other, often in accordance with structural properties like Alternating Repetition, Boundaries, and Deep Interlock and Ambiguity. Last, I've discussed the relationship between centers and patterns. Centers are pure geometric structure built from a process that makes them more whole; patterns are centers in a cultural context that solve a particular social, architectural, or aesthetic problem. The remaining question is: What is the relationship between Alexander's Theory of Centers and Alexander's pattern languages? The answer is pretty straightforward: just as centers combine to make beautiful wholes, and patterns in the world combine as generic centers to make beautiful wholes, so the written patterns can combine as a a pattern language that characterizes some whole in the world. In this column, I'll discuss the geometric nature of pattern languages. The most basic of structures![]() Figure 1. A Pattern Language of C++ Idioms A lot of patterns seem to deal with object-oriented programming, which is either a fortunate or unfortunate accident of history depending on one's perspective. The C++ idioms were among the early precursors to patterns, but they weren't originally published in pattern form. I've been reworking the idioms into patterns over the years--many of them have appeared in past issues of this column. Over the past few months I've been shaping the patterns into a pattern language for presentation at EuroPLoP '98 (Figure 1). One goal of this exercise has been to seek the overall geometric structure described by a language that ties these patterns together. The most basic structure in an object-oriented program is arguably its class structure. Most people focus on class relationship diagrams and inheritance diagrams in OO design. Object relationships are important, too, but they're a bit more elusive.
John Thomas ( In "real" physical space, there are multiple consistent (but not perfectly consistent) relationships among a number of sensory modalities. If we walk closer to something that emits sound, e.g., the apparent size of objects on the retina changes in a predictable way that is related to the amount of energy we put into the walking; the sound intensity changes in a predictable way. As I mentioned before, we've evolved to deal with physical space for a long long time and our senses seem pretty well organized around it; even our memory and thought processes seem partly organized this way. (There are, of course, some minor illusions and inconsistencies in our perceptions about space, but notice that we do "realize" that they are illusions; there are ways to test them out and our conclusion--at least in our mainstream philosophical tradition--is never that space has been acting inconsistently; only that our senses have). In fact, it's because we're so spatially oriented that illusions like this work: our minds try to force such linear pictures into three-dimensional space: ![]() In a language like Smalltalk, the primary class relationship is inheritance. Thinking about the geometry of a Smalltalk class hierarchy, one thinks of the classes and their inheritance relationships (or perhaps one includes the metaclass hierarchy, a structure largely symmetric to the class hierarchy with reflexive structures). This is admittedly an oversimplified perspective; there are other rich relationships in Smalltalk classes, most of them at a high level. C++ programs have the same general kind of overall structure, but a finer structure emerges within that overall structure much earlier in design than in Smalltalk programs. Smalltalk programs have first-class identifiers, whereas C++ programs use pointers--pseudo-objects in their own right--to simulate polymorphic name/value bindings. That means that C++ inheritance hierarchies have a richer structure than Smalltalk hierarchies from the start. (Actually, Smalltalk structures have similar structures in a different form, but it's buried deep in the virtual machine.) We know these structures as idioms: Handle/Body, Counted Body, Envelope/Letter, and others. We see these rich structures recur in C++ programs. For example, Handle/Body hierarchies leads to a pair of inheritance hierarchies that mirror each other. Their object structure is similar, except there may be more Handle "centers" for each Body "center" in the object view than in the class view.
Table 1 shows the basic geometries for each of six common C++ idioms. These might well be the sketches for their respective patterns, in lieu of the more common and mundane OMT diagrams. In these diagrams, the circles represent classes andthe boxes are objects. Classes, remember, are sets of objects, and we depict the objects as members of their classes. In the spirit of Alexander's Theory of Centers, I try to give a pleasing geometric representation of each pattern. Take Envelope/Letter as an example. The large top oval represents an analysis-time base class, and the similarly sized oval beneath it represents one of potentially several derived classes. A simple arrow between them depicts derivation or subtyping. Each analysis class is split into a handle on the left and a body on the right. In the Envelope/Letter idiom, the body object base class is the handle base class itself, so there's no body base class per se: hence, it's a dotted circle. And in most applications of Envelope/Letter--unlike Handle/Body hierarchies--only one handle base class is visible to the user. That means there are no derived handle classes. Arrows depict C++ inheritance relationships between these classes. The boxes show representative handle and body objects, with an arrow showing the pointer from one to another (note the strange symmetry with the inheritance arrow going in the other direction). Take a regular bubbles-and-arrows inheritance diagram, replacing each one of the bubbles with an appropriate structure from above. The Berkeley MetaphysicBeneath the metaphor of the geometry of inheritance hierarchies lies a more fundamental question: is it truly possible to think of software geometrically, in the same way Alexander views the conventional world geometrically? Real software structure lives on the printed page as source code. Even though there may be important geometric centers in the source structure [Coplien1998a], most designers carry mental images of software at a higher level. Alexander made it clear that his Theory of Centers was operative in three-dimensional space. He expressed doubts about "analogous space" along the heterogeneous lines of abstraction commonly used by computer scientists [Coplien1998b]: aspects, features, function, process, class, and object. He insisted that any beautiful system must be perfectly fractal in nature: "an X of Xs," to use his words. Again, John Thomas writes: Because of our ability to deal with space and geometry, we invent representations that are "like" space. We might make a three-dimensional scatterplot, for instance, of SAT scores, college grades, and starting salary. It helps us, perhaps, to "understand" the data. However, such tactics also help us misunderstand the data. SAT scores, college grades, and starting salary are not at all similar dimensions in the way that three geometric dimensions are. Not only are all three quite different from each other, but SAT scores, e.g., only range from 200 to 800 and are discrete points. And, there is no sense in which we say "for real" that the difference between 200 and 300 is "equivalent" to the difference between 700 and 800. In the May, 1998 Column Without a Name [Coplien1998b], I showed that we can meet Alexander's criteria in the source code domain. Source code exists in two dimensions on a page, and Alexander's geometric properties are clear and distinct to our senses there. Then in the July/August column, we moved on to more abstract geometries: those for the HOPP pattern and for Three-Part Call Processing. These are the kinds of images call processing people carry around in their heads, and even though they're not a formal notation (in fact, probably because they're not a formal notation) they directly convey designers' mental image of the solution. That's how they perceive it. But does this solution really exist somewhere in n-space? Berkeley, a philosopher who studied the relationship between reality and perception, asserted that Esse is Percipi--to be is to be perceived. He takes one side of a long-standing philosophical debate about whether anything has existence in its own right (if a tree falls in the forest, etc.) At first, this seems a trite argument, and an argument that's hardly relevant to the issue at hand. But things become a bit more interesting on closer inspection. Alexander found--empirically, inspired by the Mexicali experiment--that beauty owes to structures as fine as one-sixtieth of an inch in granularity. One might think that beyond the range of meaningful perception for urban planning and house design--we imagine that the important stuff must be more abstract--yet he found it to be a key to beauty. He spent years experimenting with concrete textures, and most of his subsequent work has used formed concrete as the dominant medium. Yet there are finer structures with which he doesn't concern himself: the crystalline structures of solids in the concrete, the molecular structures, the atomic structures, and so on. Those, too, are a part of conventional reality, but are beyond perception. In my early days of computer science, I could see the bits. We used core memories, and you could literally see the cores with the wires going through them. If you knew the memory hardware architecture (and many programmers did in those days when engineering was still a discipline and computer science was emerging) you could envision where the bits of a word would be laid out along the geometry of a cube of cores. You knew which core cubes held the operating system and which ones held your program, and you had a sense of how increasing addresses progressed along the cube. Sitting here on my desk, I have another old piece of memory technology called a twister card. It's a ferromagnetic sheet about 30 cm by 16 cm that was used as an early form of EPROM. I can look at it and literally see where the bits are--there are about 8 bits /cm2. In the old days, programmers used to know exactly where their programs were laid out on these cards and some of them could manually tweak individual bits to make program corrections. Most of us are taught Von Neumann memory models in terms of such geometric technologies. That leads us to form geometric program models in our heads. Few of us think of the bits of an accumulator register as being physically distributed; our perception is that they are together. However, in popular bit-slice architectures of a couple decades ago, it was likely that a given register was geographically split so that each group of 4 bits was several orders of magnitude more distant from other groups of four bits than the four bits were from each other. But that's not how we perceive it. And, following Berekley, our reality follows our perception. It starts with memory and builds up to procedures and structures as large as objects. So when we think of the instances in a HOPP pattern: ![]() we think they're really laid out in space that way. We may or may not be wrong. But it doesn't really matter. What matters is that we have a useful geometric model that maps into the real geometry, whatever that is, even if that the mapping is invisible. We can treat these problems as though they truly are geometric. The same is true in the functional programming domain, which we showed in the July/August Column Without a Name [Coplien1998c] is a paradigm that lends itself to natural geometric expression much better than the object or procedural paradigms. Furthermore, we think of class hierarchies as being contiguous, as if their source code abutted in the program image. If the only way we perceive classes is through a browser of some sort, then that reality is borne out further by the perception. And what browsers bring to the class world, tools like Kent Beck's Object Explorer bring to the instance world for Smalltalk programmers (I've seen similar tools for C++ but don't remember their particulars). Organizational patterns are another interesting data point [Coplien1996]. We don't literally see the social network of an organization in the workplace. The social networks provide a spatial metaphor for communication distances. What's interesting is that these metaphorical social structures most often correspond to real geometric structures: the layout of the offices belonging to the people in the organization. A bird's eye view might well unmask the literal geometric structure that shapes communication in any professional culture. Our world really is geometrical. And it's that way because we make it that way. Creating RealityObject-oriented software tries to mimic the reality around the designer; Bertrand Meyer has often said that the "objects are just there for the picking." But software development isn't so much the art of capturing reality as it is of creating a new reality. In a thought-provoking series of essays, the book Software Development and Reality Construction [Floyd+1992] argue persuasively that design isn't so much the act of capturing reality as of creating one. Is the reality in our head a geometric one, one that reflects our species' experience with the world over the millennia? Or is our internal model of the world--and of software worlds in particular--something totally different? The GateA postscript of sorts: To Alexander, these issues of geometry aren't just about models of perception. To him, they grapple with the very structure of matter, with how the world really is. If I ask the analogous question for software, whether it really does live in some multi-dimensional world in the same sense that buildings do, they'll probably take away my license to do real work and suggest I go write poetry or something. So for know we'll stick to Berkeleian metaphysic. Kind of sad, isn't it? SignpostsThanks much to Pete McBreen for the visual puzzle. Have fun at OOPSLA, October 18 - 22, in Vancouver. In the January 1999 issue, I'll present the first half of the C++ idiom pattern language, with the second half appearing in the March/April 1999 issue. References
|








