Thursday, April 14, 2005

AOP

It occurred to me that AOP corrects many of the deficiencies in Java that cause me to consider it less robust than C++: most importantly, its inability to guarantee pre- and postconditions after the fashion of RAII. I haven't got time to do a formal comparison, so I would be interested to know anybody's opinion on the following topics:

  • AOP techniques that can't be represented adequately in "pure" C++ (and by adequate I mean with the same degree of isolation).

  • C++ techniques that can't be represented adequately in AspectJ.

Monday, April 11, 2005

Dispatch Tables in Python

I mentioned dispatch tables last time around. Dispatch tables are basically dictionaries of functions. Here's a concrete if trivial example of how to use them, written in Python.


class Document:
def __init__(self):
self.dtable = {
"color": Document.setColor,
"text": Document.addText
}
def setColor(self, rgb):
# set the pen colour for the document
pass
def addText(self, text):
# add some text to the document
pass
def loadXml(self, node):
while node:
self.dtable[node.nodeName](self, node.data)
node = node.nextSibling


As you can see, the loadXml function itself knows nothing about what XML nodes might occur, or what functions must handle them. This is important because it allows code to handle new nodes (or change the handling of old nodes) to be added in, say, a subclass without changing the original class at all. All that is needed is to modify the dispatch table (dtable). This is a powerful technique, and much used in Lisp and C. It has several advantages over a more conventional if-then-else approach:


  • It's more elegant. In most languages (with the curious exception of Java), this technique takes less lines of code and is easier to work with. Fewer lines of code equals fewer mistakes.

  • It's more robust. A mistake in one case won't topple the other cases. There is more separation between the handlers for various types than with some other techniques; also, the dispatch mechanism need know nothing specific about the handlers.

  • It's future-proof. The mapping of metadata to interpretation is independent, in most cases, of the dispatch mechanism. Changes to input data formats, for example, can be handled with minimal intrusions into existing code.

  • It's faster. Surprised? A dictionary look-up is ideally O(1); a chain of ifs is O(n).