Meta Matters!
What do all (ok, most) of today's hypes -- MDSD, Ruby (on rails) -- have in common? Meta! I think that having access to the meta level gives you that extra bit of power you need for efficiently developing applications.
So, what does meta mean? Meta is greek and basically means "about". So, if you have a metamodel, then you have a "model about a model", i.e. a model describing the model at hand. If you've got a meta program than you have a program that knows something "about" the program you talk about.
So let's try to put some systematics into "meta". I think there are three dimensions that you have to define when talking about meta:
- When do you have access to the meta level? Is is before the program runs (as in code generation), during compilation (compile-time meta-object protocols) while the program loads (bytecode rewriting) or during the program's execution (reflection and runtime meta-object protocols)?
- What can you reflect about? Is it a program (as in reflection in Smalltalk, CLOS or Ruby) or is it more abstract models (as in MDSD)?
- And then finally, what you can actually do with this meta information? Can you only read it (as in Java's reflection), can you actually modify the structures you reflect upon (as in Ruby or in an MDSD generator), or can you reify the meaning of what you see (as in CLOS' meta-object protocols)?
There are certain especially useful combinations of these dimensions:
- In dynamic, reflective languages such as CLOS or Ruby you reflect on program structures. It happens while the program runs! So, while running a program you can reason about and also change the structures of the running program. Sometimes you can even change the semantics by changing the interpreter at runtime (e.g. in CLOS). Note that for write access to the program you need some kind of interpreted system - since you want to change program structures at runtime.
- In MDSD, you typically reflect on models using the metamodel (and maybe the metametamodel). Reflection happen before the program described by the model runs. You can read and write the model. Note that, technically, the generator is a model interpreter that can change the model during its own execution.
An especially nice trick is the following: If you use a language without reflection capabilities (i.e. without access to the meta layer) such as C or C++, and if you generate the respective program using a code generator, you can use the code generator to build your own meta layer into the program - enabling reflection, at least read-only, during runtime. This works since the generator has the meta information available (it's an interpreter...) and can put it into the generated program structures.
So? Where does this take us? Maybe it shows that the two approaches (MDSD and the new, dynamic languages) are not that far apart. And it also shows what is really the essence of the two approaches. However, all of that is not new. CLOS, for example, has had all that a long time ago. Why didn't it catch on? The reason is that this meta stuff isn't always trivial to understand and use... let's see how it catches on this time.