February 13, 2005
C++ metaprogramming framework
I was eager to try out test driven development on another project, this time something a little more substantial. So I started out by thinking what my first test should be. I considered using TDD to write the DDL preprocessor. But I wasn't sure what it should do exactly. I realized that this wasn't really programming by intention.
Then I decided to start by thinking about what kinds of things the users of the CDL would want to do. I came to the conclusion that it wasn't the CDL itself that was important but its application. Indeed, if using CDL and reflection is an appropriate thing to do, then TDD would hopefully lead me in that direction.
The most useful application is probably automatic serialization. So I decided that my short-term goal should be write a program that saved the state of some simple test objects to a stream. Eventually this would be achieved using serialization code automatically generated from the CDL.
But to get things started, I would "automatically generate" the code by hand. Once the amount of "automatically generated" code started to get unmanageable, I would have a good idea of what the CDL preprocessor should do and I would be able to use TDD to start writing it. Having got a basic CDL preprocessor and a basic runtime framework underway, I would be able to use TDD to evolve them in parallel.
Some interesting things happened. First, I ended up not using TDD. Perhaps I don't get it yet but I found that it was taking me too long to make progress and that I was taking a lot of wrong turns. I found it was more effective to hack together a series of throw away prototypes. The trouble I am having is that I still don't know exactly what the problem is. I understand the problem in C# but I don't yet fully understand how to translate it into C++.
I am still using some of the ideas of TDD. For example, I am still programming by intention and I am finding it to be very useful in shaping my prototypes.
Also, this approach did not lead me to a CDL + reflection solution. Rather, it lead me to a metaprogramming solution. What I have at the moment is a system where I use CDL to describe my classes. The CDL is just a subset of C++ that should be easy to parse and analyze by the preprocessor. From the CDL, I "automatically generate" (still by hand) C++ code that performs serialization.
This differs from reflection. Using reflection, I would automatically generate a data structure that some general purpose serialization code would query at runtime.
Metaprogramming is quite natural in C++. C++ already supports metaprogramming with templates. What I am aiming at now is a more powerful and easy-to-use metaprogramming framework to automate information processing tasks such as serialization and GUI generation. While template metaprograms work by using templates as a rudimentary compile-time functional programming language, my metaprograms will just be normal C++ programs that are run as a pre-build step. They will probably take a tree representing the parsed CDL as input and generate C++ code as output.
I will post some example use cases for CDL in my next post.
SBL - software development
I want to learn C++ in my spare time. I don't have much experience but I think I'm up for the task.
Do you know where I can find a good internet resource? Thanks.