hide all comments

DSM-tech

DSL Tools Lab shows pain of constraints in C#

November 12, 2008 17:06:46 +0200 (EET)

Microsoft have a new DSL Tools Lab for beginners to learn how to use DSL Tools in one day. Full marks to Jean-Marc Prieur for starting off by explaining that modeling languages should be based on the problem domain, not the solution domain:

[Y]ou want to create a vertical language that is suitable for your business, and from the models that the language manipulates, generate the code for your business Framework. Nevertheless, because it is difficult to ensure that everyone who takes this training knows the professional tasks that are addressed by the targeted business Framework, we will settle for a horizontal (that is, technical) DSL.

The example language is thus a simple state machine (why is it always a state machine?!). The part that interested me is Part 3, Validation and coherence of the model. Let's look first at how to display the label for a transition. A transition specifies an Event that causes it, a guard Condition that must be true for it to be followed, and an Action that is taken when it is followed. All of these are written in the example as C# code snippets (tut tut :->). They want to display them as one single label, formatted as "Event [Condition] / Action".

Here's how to do it in DSL Tools: four pages of dense (8 pt font!) instructions and code, total 242 lines:

Formatting a transition label the DSL Tools way

And here's how to do it in MetaEdit+: three lines of MERL in the transition symbol's label:

:Event
if :Condition then ' [' :Condition ']' endif
if :Action then ' / ' :Action endif

About 10-15% of the DSL Tools solution is taken up by what I'd say is a really bad idea: storing the calculated label as a property in the transition alongside the Event, Condition and Action -- effectively duplicating that information. This also means they need to be able to parse the syntax of the label if it is edited, to update the other three properties.

Next, let's look at how to ensure there is only one Initial State. First, the DSL Tools way: just into the 4th page of 8pt instructions and code, total 200 lines:

Ensuring only one Initial State the DSL Tools way

And here's how to do it in MetaEdit+: a simple Occurrence Constraint for Initial State in graphs of type State Diagram:

Initial State may occur at most 1 time

The lab goes on to mention several other possible constraints and checks, but doesn't show you how to implement them (presumably since the intention is to finish it in one day). Here they are, along with how to implement them in MetaEdit+ -- I just tried, and it took just over a minute to do all five:

  • Final States should not have an exit transition
    Normally this would just be in the Binding for Transition, which specifies for each role (end) of the relationship which objects it may connect to: Exit (State | Initial State), Enter (State | Final State).
    Another way would be a connectivity constraint: Final State may be in at most 0 roles of type Exit
  • Entry and Exit actions of the States must have non-blank code
    The Value Regex for the code property in the Actions would be .+
    Actually, I think this is an unnecessary requirement: many states have no entry or exit action.
  • Names of States must not be blank
    The same Value Regex as above.
  • Names of States must be valid C# identifiers
    Change the Value Regex to something like [a-zA-Z_][a-zA-Z0-9_]*
    Again, I think this is a poor requirement: much better is to allow modelers to type whatever seems sensible, and then turn it into a valid identifier when outputting. In MERL you can use translators to do this, e.g. :Name%var. Using %var translates the :Name property's non-identifier characters into underscores; you can create your own similar translators, e.g. "%upper a-z A-Z" translates lowercase characters to uppercase.
  • Names of States must be unique in a State Diagram
    A Uniqueness Constraint for State Diagrams: Property "Name" in State must have unique values
    Note that this is per diagram: if you want States to have unique names in the whole repository, you can mark the Name property in State as unique.

Hopefully this gives some idea of how easy it is to add constraints and checks in MetaEdit+. With experience from making hundreds of modeling languages over the last 15 years, we have a pretty good idea of what kinds of constraints you actually need. That allows us to offer you simple ways to define them, without having to resort to hundreds of lines of hand coding for each. And there's no "customization cliff": if you have something we haven't thought of, you can just write it in MERL, or in whatever language you want via the API.