05/09/09 :: [MOP] More on Implementation Elements [permalink]
Implementations elements are the core of MOP, they are the main difference between anemic and cogent DSL and represent a key enabler of polyadic programming models (PPMs).
The question becomes how do you specify these elements in a DSL? In traditional textual-DSL approaches, there is no real difference between them and the DSL element definitions. For instance here is an textual-DSL that specifies an orchestration language in xtext (openArchitectureWare).

As you can see, the "syntax" of the implementation elements (here Orchestration) have no real boundary with respect to the other elements of the metamodel (Message,...). You kind of guess that you are now dropping into an implementation element because you are opening a curly bracket (which is not always true). Worse, textual-DSL frameworks force me to (re-)define the implementation syntax (AlgebraOperators, LogicOperator, Connector...).
The corresponding Abstract Syntax Tree associated to an instance document (i.e. in this case, an orchestration definition) makes again no difference between the metadata and the implementation, they all look the same in the AST (the AST is on the right-end side):

As Cogent DSLs (c-DSLs) are being defined by traditional textual-DSL frameworks (since textual-DSLs are conducive to defining implementation elements), the c-DSLs designers will design ad hoc syntaxes will no or little verification possible. This will create a significant impediment to the development of c-DSLs as we can expect a "babelization" of the syntax definitions while making runtimes and interpreters harder to build.
The question is how can we provide reusable implementation element specifications? It is actually quite trivial, if only you care to understand that this is a problem. The key is to define an M3 layer (if you don't have one) or add a dimension to more traditional M3 layers (Ecore, KM3...). How would that M3 layer work? Let's take a 3 element DSL (i.e. metamodel):

I defined the M3 types as "C", "D" and "S". They are abstract types and carry some specific properties common to all metamodel elements that are "stereotyped" with this abstract type. What the metamodel says here is that Element1 has two or more operations and these operations elements can manipulate Element3 instances in addition to Element1 instances. However, these operations cannot manipulate Element2. Not that this independent of any relationship that may exist or not between these elements at the metamodel level.
What do I mean by manipulate? Well, this is where the metadata specified at the M3 level comes to play. For instance once of the key elements is the lifecycle of a particular abstract type. For instance type "C" has this kind of lifecycle:

That's why it has to have at least two operations (one constructor and one destructor).
"D" elements have this type of lifecycle:

And you guessed it, the "S" element has this type of lifecycle:

There are a few other things that need to be defined to fully specify these implementation elements, for instance the type: procedural, orchestration-based, template-based... You could even declare your favorite "syntax": Java, C#, Objective-C, C++, APL ...
As far as I can see, nobody has spent the time to define that level in the textual-DSL world: Intentional Software, OpenArchitectureWare, JetBrains... Even KM3, though extremely compact and well designed, does not offer the possibility to differentiate between implementation elements and the other elements of the metamodel.
As you can see this is not a question of textual vs visual, it has nothing to do with that. The question is: Cogent vs Anemic DSLs and Monadic vs Polyadic Programming Models. So far, Software Engineering has always been based on monadic programming models and anemic-DSLs:

Polyadic programming models and cogent DSLs, such as ASP.Net for instance were only achieved by a combination of anemic DSL and monadic programming model (via code behind). You will notice that at this point I don't make any difference between a general purpose language like Java and a DSL. Java is just a cogent DSL that defines a monadic programming model. Similarly, WSDL is a (totally) anemic DSL that "participate" in monadic programming models. It of course does not define a programming model itself.
Creating programming models was hard to do in the visual-DSL era, but a lot more people are going to be tempted to create cogent-DSLs using current textual DSL frameworks. These new cogent DSL will inevitably lead to polyadic programming models. Polyadic programmind models already exist: HTML+JavaScript or ASP.Net + code behind are a good approximation of PPMs. However, these programming models were developed without a strong modeling foundation.
We still have a choice today to innovate and understand how cogent DSLs can help us create Polyadic Programming Models or we can go the "classical" route and treat everything and everyone equally in the AST with an implied MOF-like M3 layer. We have the opportunity to open the door to architecture refactoring and architecture independent solution models. We have the opportunity to advance the state of Model Driven Engineering or remain classical, we have the opportunity to dramatically improve productivity of our industry in an increasingly complex architecture landscape or we can define corny rules around coupling and cohesion, invent new monadic programming models (such as the (other) REST), or return to Functional programming.
We are at a point where solutions models and architecture need to part. General Purpose Languages will stay on the architecture side while cogent-DSLs will take over the solution space. There is simply no other path of evolution.