Untitled RSS

Archive

Apr
7th
Tue
permalink

Truth in Metaprogramming

I find it convenient to distinguish between two types of metaprogramming.  One kind augments the source code, the other kind nullifies it.

Ideally, whenever you see behavior in the source code you know that it is accessible in the precise way outlined in the source.  For instance, if a class named Registry has a method named getProperty, we should have confidence that when we send the getProperty message, the registry will do what the code of getProperty tells us that it will do.

When we can open classes and replace behavior, we can easily violate the understanding that is implicit in the code.  We can, for instance, have getProperty do something entirely different.  In general, this is bad.  It makes the existing code a lie.

When metaprogramming is used well, it augments the behavior in the code.  We might look at a class and see three methods.  In some other place in the code we might be able to add two more methods to that class.  Does this make the original class definition a  lie?  Not really.  The behavior outlined in those three methods is still there, and accessible, it’s just not the complete story.  Methods added to the class from someplace else do not not make the original three methods “untrue.”

At its base, this is really a variation on an old design principle called ‘The Principle of Least Surprise.’  In Object-Oriented code we can see in in the ‘Liskov Substitution Principle’: subclasses should not violate expectations clients have of their superclasses.  It’s interesting to note, though, that LSP violations often occur when we replace behavior by overriding it in subclasses.  In other words, when we do precisely the thing that we should avoid in metaprogramming.

Code should never lie.  In general, it’s a good idea to use metaprogramming to augment behavior, not replace it.