09/12/09 :: [MDE] Metamodel Oriented Programming (RE)Explained[permalink]

I have tried to explain Metamodel Oriented Programming to a few people over the last few months and I felt that I was just getting some polite interest at best. So I'd like to try to explain it a bit more.

I have created this diagram to classify executable artifacts (interpreted or compiled):

The Anemic - Cogent axis could have just been called Declarative - Imperative. It refers to whether an artifact contains "implementation" elements. An example of implementation element is a method in an Object Oriented Class.

The Monadic - Polyadic axis simply reflects the number of concepts that make up the structure of the artifact. OO languages typically have one (major) concept: a class, so they are monadic. DSLs like HTML or SCA have several. For instance SCA has: Service, Component, Composite, Domain, Assembly, Wire, Event,...

HTML is interesting because it is probably the most successful DSL on earth. Lots of people are surprised when I call HTML a DSL. I am not sure I am wrong in doing so. Yet, HTML without Java Script (i.e. an anemic HTML) would be quite a bit less useful. I am not sure the Web would be what it is today without the cogency that JavaScript brings to HTML.

SCA is also interesting because it shows how you can augment all sorts of general purpose language with a DSL: SCA + Java + BPEL starts looking a lot like a Polyadic Cogent programming model. SCA alone though is completely anemic.

This figure calls for a missing category of languages: Polyadic Cogent programming languages. So that bears two questions:

1) what do they look like?
2) what are they good for?

What does a Polyadic Cogent Programming Language Look like?

First, it is polyadic, so pick your favorite (anemic) DSL, here is one with 3 concepts (the more the merier):




Now add some implementation elements to your DSL, just like in OO, a class has a method:




You can of course choose the multiplicity of the implementation element (0,1 or more). A (SOA) Service is interesting because it can have 0 or 1 implementation, depending of whether the Service Implementation is based on a BPEL orchestration or if each operation is implemented individually. Yet, the implementation elements (BPEL or otherwise) are all completely separate from the Service Definition (WSDL). If it is a good thing to have a separate contract definition, it also hides completely the programming model behind SOA, and that's bad. It has lead to all kinds of interpretations and frankly poor implementations, frustrations and clueless analysts talking about the death of SOA.

So at the metamodel level (M2), you just add an Implementation element, but what do write it at the metadata level (M1)?

First you need some processing instructions and basic types. There are two type here: your favorite Turing complete set and an orchestrated set. We should probably combine them both and add events to the mix and have just one standard processing set which could be personalized with your favorite syntax.

The second type of instructions is related to the lifecycle of the elements in DSL: A, B, C. When you say:

A a = new A();

you are simply starting the lifecycle of an instance. Similarly, a Class in an OO runtime has a simple lifecycle: Loaded, Unloaded. A service, in a service container has a couple more states: Loaded -> Started -> Stopped -> Unloaded. Please note that some of the states and transitions may be implicit (e.g. delete() or gc() ).

So just define the lifecycle of each of the elements of the DSL, assign a catchy name for each transition between states and voila, you have your Polyadic - Cogent programming language.

I don't know why the DSL people hate code (i.e. implementation elements), I don't know why the GPL people keep adding annotations or stitching code behind your DSL. These approaches simply don't make any sense.

Nothing is simpler and cleaner. You have complete control over what the language can do, you can even add constraints about which transition a particular implementation element is allowed to call. I can create very robust Polyadic Cogent languages in a couple of days using tools like xtext from openArchitectureWare.

What are these languages good for?

Well if you see the number of annotations floating around these days, Polyadic Cogent Languages should be able to clean up this in no time. At the end of the day an annotation is a just a DSL element and people want to use the syntax of their favorite language to add some implementation element to that particular DSL element. The problem with this approach is that we put a class wrapper around this DSL concept and we let developers loose do whatever they want with the class. This approach is wrong: we are introducing vast amounts of inefficiencies with that, for absolutely no gain at all. SCA's annotations in Java are a perfect example of this problem. Don't get me wrong I really like SCA, but wrapping services (with bi-directional interfaces), wires, composites and what not behind Java Classes is introducing levels of complexities that can easily explain why SCA is not used more. The more polyadic your DSL will be the messier it will be to use annotations.

The same thing is true of code behind (not to mention annotated code behind). Code behind is a bit more aligned with MOP as it is based on events (occurrence of a state), but there are no clear separation between the code associated to each metadata element (like a class - method relationship). The code is generally behind a metadata set and generally exhibits poor reusability and factoring.

Annotations and Code Behind approaches are introducing two dire side effects:

1) there is no clean separation between the metamodel level and the underlying container of the business logic (expressed solely from Metadata and Implementation elements)

2) they prevent the metamodel to span multiple tiers of the architecture

I cannot emphasize enough how bad this coupling between metamodel / container is. Architecture has been widely successful over the last 15-20 years. We have been able to create sophisticated distributed systems that bring tremendous value to their users. No question about that. The problem though has been stitching all these tiers together with lots of boiler plate code, often hand coded, always hard to change.

Today there is a great need to create architecture independent programming models:

This is exactly what a Polyadic-Cogent Programming Language can do, spanning n-tiers, from data to presentation.

Too many companies are stuck today with what they built over the last 10 years. The containers are going out of support and yet they can't change them because they wrote all the business logic within the containers, using their APIs.

In a Cloud world, it is even more critical to be able to create architecture independent programming models.