Hmm, my first blog entry. To get started, I’ll just write about a book I’m reading these days.
I have a confession to make: I have been guilty of discarding some of the OOP patterns as “just papering over the weaknesses of OOP languages”. For example, the Visitor pattern has been discarded as “it is just fold”. However, lately I’ve been reading a few C++ books (because my new job involves a lot C++ coding). One of the books I’m reading (for the second time) is Andrei Alexandrescu’s book Modern C++ Design, which is about how to implement patterns using C++ templates. In the introduction of the chapter about the Visitor pattern Alexandrescu first write:
To do this [enhance the functionality of a given class hierarchy], you can either add new classes or add new virtual member functions. Adding new classes is easy … [snip] In contrast, adding new virtual functions is difficult. To be able to manipulate objects polymorphically (via pointers to the root class), you must add virtual member functions to the root class, and possibly to many other classes in the hierarchy. This is a major operation. … [snip] In a nutshell, from a dependency standpoint, new classes are easy to add, and new virtual member functions are difficult to add.
At this point I has nodding to myself and thinking something along the lines: “What a clear description of what is wrong with OO programming languages”. These problems with OO languages are of couse well known, it is, for example, similar to what Xavier Leroy said in his invited talk at ICFP’99. I was just using Alexandrescu to confirm my prejudices. But Alexandrescu wents on:
Visitor trades the advantage you don’t care about [to add new classes with ease] for an advantage you need [to add new virtual functions to a hierachy easily].
This is the important insight. And it an insight that I’ve completely overlooked until now. I think that this way of looking at programming patterns is useful: look for advantages you don’t need and see if you can trade them for advantages you need. I also think that this is useful viewpoint for type systems and programming languages in general. For example, in C/C++ you have the advantage that you have full control over memory management, and this advantage can in some situations be used for writing efficient programs. But sometimes you are willing to give up that advantage for the advantage of automatically handling of memory management (i.e., a garbage collector).
Back to Alexandrescu. His book also made me realise that the Visitor pattern probably corresponds more to a
case-expression than to a fold-function, at least Alexandrescu doesn’t give a concrete example that handles recursion. Perhaps, I should have paid more attention when I read the GoF. All in all, I can recommend Alexandrescu’s book as a fine supplement to the GoF (if you are into C++ and don’t mind templates).