hide all comments

DSM

Linux, Git, MetaEdit+: how three Finns brought versioning, models & code together

September 20, 2018 13:32:21 +0300 (EEST)

Coders are often accused of being allergic to modeling, but I'm not sure that's true. I think we're just allergic to wasting time, to going through the motions to satisfy some meaningless rule, without actually producing anything worthwhile. And most of all we hate having to do the same thing twice. So management-mandated post hoc UML for documentation was never going to fly.

We love our language, our frameworks and our tools, and it takes something pretty big to get us to break away from them. Modeling may be great for non-programmers, who like the visual format, but it's no substitute for code. Usually.

The most common case I've seen that persuades programmers to use modeling is state machines. If...elseif or switch...case just cannot make things clear, and neither do textual DSLs, whereas graphics work well. Even Linus's kernel GitHub contains a state machine diagram — albeit in ASCII art!

 *             |
 *             V
 *    +---> STARTUP  ----+
 *    |        |         |
 *    |        V         |
 *    |      DRAIN   ----+
 *    |        |         |
 *    |        V         |
 *    +---> PROBE_BW ----+
 *    |      ^    |      |
 *    |      |    |      |
 *    |      +----+      |
 *    |                  |
 *    +---- PROBE_RTT <--+

The horror and time wasted trying to use ASCII leads most to an actual graphical tool. And rather than draw then code or vice versa, with all the usual duplicate effort and things getting out of sync, we should be able to keep the state model as the primary source for this part — just like we have bits of our projects in other languages, when that's the best format. Providing it all gets automatically built and integrated, and versioning works as expected, that's fine. Except, it generally doesn't: hence the ASCII art.

So can we change that: make it possible to sensibly integrate code and models, and to version both? And without horrible amounts of extra work to set up, or (particularly) when using it? And are you sick of the rhetorical questions and want to actually see the darned thing?

Three Finnish amigos: Linux, Git and MetaEdit+

Since the gold standard for coding is Linux, and the gold standard for versioning is Git, and both are Finnish, let's see how adding a third Finn into the equation can help. MetaEdit+ is a modeling tool, and also a language workbench (a tool that makes it easy for you to create your own modeling languages and code generation). Conveniently, it also supports Linux, Git, and integration with other tools like IDEs. And it has a nice little 'digital watch' state machine example with full code generation.

Full code generation?! Is this going to be some horrible flow chart with IFs, GOTOs, and inline code snippets with no IDE support? Or bulky, unreadable, inefficient blub code? Fortunately not. Both the graphical language and its code generator are domain-specific, i.e. fine-tuned for this task (making digital watch apps). So there will be things anyone will recognize, and things that may be new if you've not worked in this kind of domain, but it should be understandable on both model and code levels.

Diagram watch

Here's a diagram of a Stopwatch app. The watch can be in various states, and you can press buttons to cause actions and move to a new state. Actions are things like setting time variables or turning on an icon on the display. In short, the language lets you specify things from the point of view of an end-user of the watch, with the code generation and a little state machine framework taking care of the innards.

You can grab MetaEdit+ for Linux (and its Eclipse plugin if that's your IDE) to follow along. See the Watch Example for more details. 

Models to Code

Let's take a look at the code, then. Select the top-level WatchModels graph from the Graph Browser pane in Eclipse, and from its pop-up menu choose to edit the Graph's Properties... and set the Generation target platform to 'Java: Linux'. Select and open the pop-up menu again and choose Run Autobuild. (If you're not on Eclipse, select WatchModels in the top MetaEdit+ window's Graph Browser tab, from its pop-up menu those pop-up menu choices are Properties... then Generate... | Autobuild.) The code will be generated (and either added to an Eclipse project if using the plugin or opened in a Generated Files window if not), compiled and run.

Generated Files

Java WatchModels Java Stopwatch

We can start the Stopwatch by choosing the Sporty WatchModel, then pressing Mode. As we can see from our model, pressing Up starts it running, and Up again stops it. Pressing Down will then reset it.

Models to Git

OK, so we have models, we have (generated) code, but what about versioning and collaboration? MetaEdit+ has a multi-user version that automatically keeps everyone in sync, without any merges or locking people out while others edit. Nice, and overcomes the nightmare of merging model changes, but still doesn't give us versioning. For that, we can use your normal Git or SVN. Let's assume you want a local Git repo that will also be pushed to GitHub or BitBucket.

First, fork the https://github.com/MetaCase/watchdemo repository into your own GitHub (or BitBucket). In your ~/metaedit directory, mkdir git. Add this new directory and your Git account URL (without /watchdemo suffix) to a ~/metaedit/.vcsPaths file like this:

gitBaseDir=/home/myuser/metaedit/git
gitBaseURL=https://github.com/myuser

Exit MetaEdit+, and ensure you have xterm installed, as the Git and SVN integrations use it. Then run the following command to get a local clone of your online repo:

metaedit textForMERL: "_vcsInitClone('watchdemo')" logoutAndExit

You'll be prompted for your GitHub/BitBucket password in an xterm, and assuming all goes well you can close the xterm at the end. Using the Eclipse Graph Browser toolbar buttons, Refresh it and change its Settings to point to watchdemo as the Repository name. Restart MetaEdit+ from the Graph Browser button. To see what changes were made to the original, see "Extending the modeling language" in the previous blog entry.

Freedom through code

Open the Stopwatch graph by double-clicking it in the Graph Browser (Refresh if necessary, then WatchModels->TST->Stopwatch). If we look at the model for the Down button's action at the top, we can see it's a bit ugly: resetting startTime to zero by setting it to stopTime - stopTime. The 'official' Watch Example tutorial uses that as an excuse to improve the modeling language by adding constants, but here let's use it as an excuse to integrate some 'real' code. Let's have the model just specify a function to call, and we can then implement it in code to do what we want.

Select and delete the startTime, startTime and stopTime connected to the Down button's Action. Click Function on the toolbar and click on the diagram to add a Function called 'reset', then click the Run relationship's ! icon on the end of the toolbar and drag from the Action to 'reset' to connect them (just OK the dialog: there's only one action here, so we don't need to set an order).

Diagram reset

Trying out the integration of hand-written code

Now we can generate the code for our model, build it and run it. Select the top-level WatchModels graph in the Graph Browser and Autobuild again. Choose Sporty, press Mode to get to the Stopwatch application, and press Up a couple of times to start and stop the stopwatch. You'll then be back in the Stopped state, seeing the time you measured. For now, pressing Down in the Stopped state will not change the displayed time: it calls the reset method, but that has no body yet, so does nothing.

In the generated Stopwatch.java file, edit the reset method to add a line between the leading and trailing MD5 comments, to set stopTime to zero, then Save:

		setStopTime(new METime());

(Note that we're editing a generated file: normally this is a no-no, but here the MD5 protected region will take care of things, maintaining our manual code but regenerating the rest from the model.)

Eclipse reset

Close the running Sporty and WatchModels. Rebuild the WatchModels with Autobuild, and try Sporty again with the Mode, Up, Up, Down steps, and see that Down now does reset the stopwatch time to zero.

Combining models and code in Git

So now we have our models in Git, our standard code generated, our custom code added by hand and maintained automatically. The last thing to do is extend the Git integration so that the manual code also gets included when versioning models. (Where possible it would generally be better to keep the manual code more separate from the generated code, but we deliberately chose the harder path here.)

The MetaEdit+ Git integration is handled by generators, so you can tweak it to your needs. In the main MetaEdit+ window, choose Repository | Changes & Versions Tool, choose VCS Settings | Paths, and add the following lines after the settings for $dbName and $dbBaseDir:

/* $srcDir is for source code you also want versioned; '' for none */
$srcDir = __(subreport '_default directory' run 'WatchModels' sep 'src')

Save that and select the _vcsCheckIn generator further up in the list, then add these lines about 2/3 down before its _osCd($vcsWorkingDir) line:

if $srcDir then
   _osCopy($srcDir sep '.', $vcsWorkingDir sep 'src') ' || ' _osPause() newline
endif

That will copy the contents of the $srcDir to our Git directory when we check in with Save Version. Likewise, if we ever check out we want to copy the source out of Git, so save that, edit _vcsRestoreDB and add before the last line (pushd):

if $srcDir then
   _osMkdir($srcDir) ' || ' _osPause() newline
   _osCopy($vcsWorkingDir sep 'src' sep '.', $srcDir) ' || ' _osPause() newline
endif

As you can see, we create $srcDir to be on the safe side. Those _osMkdir and _osCopy calls are simply subgenerators that produce the right batch / shell commands on the current platform, so we can write these versioning scripts once rather than duplicate the logic for each platform. ' || ' _osPause() will pause if the command gives an error, so we can see what the problem was.

Finally, if we're using the Eclipse plugin then the source code won't be stored in the normal MetaEdit+ location that we set in $srcDir, so we can override that on this machine by adding a setting for srcDir in the ~/metaedit/.vcsPaths file we made earlier. Enter the absolute literal path from the Eclipse Properties of the src directory, something like:

srcDir=/home/myuser/eclipse-workspace/WatchModels/src

Versioning changes

Go back to the Changes & Versions tool and press Refresh (or open it again from the main MetaEdit+ window's toolbar or Repository menu). That will show you the changes since the previous version, i.e. changing the Stopwatch zeroing to use the reset object. You can see the changes in the tree, or from the pop-up menu of Stopwatch: Open shows them graphically, and Compare shows them textually.

Select the top Working Version, and enable Show All Versions to see previous versions. Enter a new version number and version comment, e.g. 9 and 'Added reset function and srcDir'. Try a Save Version, both for testing and to commit the changes we made to the model and the version control generators (if you type your password wrong or something similarly simple, you can rerun from your ~/metaedit directory with metarun gitCheckIn.bat).

You can see from GitHub/BitBucket that as well as changes in the repository (versionedDB/) and the addition of the source code files (src/), we also save the generators as text files (metamodel/Graph/) to make it easy to see what's changed.

Add some new functionality to the model itself, e.g. a Laptime state. Autobuild again and see that the hand-coded line in reset() is maintained. Save Version again and see that all is as expected in the remote Git.

Summary

So, we took an existing modeling language and its generators, and added a couple of nice things:

  1. Set it up to version locally and to GitHub/BitBucket, with just two settings values
  2. Extended the Git integration to also version the manually edited code. Edit freely in MetaEdit+ and Eclipse, then version everything together with Save Version.

It's interesting to note that none of the things we changed here had been specifically set up with these use cases in mind. By building tools with the parts that might need changing accessible, understandable and open source, even quite extensive changes can be made easily. That was true on all three levels:

  • model: adding 'reset' and its manual code gives easy freedom to the modeler
  • metamodel: extending the modeling language and its generators for hand-coded Functions: see previous blog
  • tooling integration: extending versioning to generated and hand-edited source code files.

Oh, and while MetaEdit+ is as Finnish as Linux or Git, we're pretty cosmopolitan too: the versioning integration above works for Windows, SVN etc. as well.

DSM

Combining hand-written code with generated code

September 20, 2018 13:05:06 +0300 (EEST)

There are many ways to integrate hand-written code with generated code. The easiest end of the scale is also the most common: generated code that calls, references, subclasses or otherwise uses hand-written code. There, the two kinds of code can lead separate lives, just like any reusable component need not be aware of, nor should be tightly integrated with, code that uses it. The hand-written code isn't specific to a particular model. At the other end of the scale are cases where the models can't capture everything that might be needed, and we need to add hand-written code at specific points of specific models. Although there are often ways to avoid this, let's take it as the hardest case, and see how good tooling can cope palatably even there.

Diagram watch

Here's a diagram of a Stopwatch app. The watch can be in various states, and you can press buttons to cause actions and move to a new state. Actions are things like setting time variables or turning on an icon on the display. In short, the language lets you specify things from the point of view of an end-user of the watch, with the code generation and a little state machine framework taking care of the innards.

You can grab MetaEdit+ (and its Eclipse plugin if that's your IDE) to follow along. See the Watch Example for more details.

Models to Code

Let's take a look at the code, then. Select the top-level WatchModels graph from the Graph Browser pane in Eclipse, and from its pop-up menu choose to edit the Graph's Properties... and set the Generation target platform to 'Java: Linux'. Select and open the pop-up menu again and choose Run Autobuild. (If you're not on Eclipse, select WatchModels in the top MetaEdit+ window's Graph Browser tab, from its pop-up menu those pop-up menu choices are Properties... then Generate... | Autobuild.) The code will be generated (and either added to an Eclipse project if using the plugin or opened in a Generated Files window if not), compiled and run.

Generated Files

Java WatchModels Java Stopwatch

We can start the Stopwatch by choosing the Sporty WatchModel, then pressing Mode. As we can see from our model, pressing Up starts it running, and Up again stops it. Pressing Down will then reset it.

Freedom through code

If we look at the model for the Down button's action at the top, we can see it's a bit ugly: resetting startTime to zero by setting it to stopTime - stopTime. The 'official' Watch Example tutorial uses that as an excuse to improve the modeling language by adding constants, but here let's use it as an excuse to integrate some 'real' code. Let's have the model just specify a function to call, and we can then implement it in code to do what we want.

Diagram reset

Extending the modeling language

To follow these instructions, you should be familiar with MetaEdit+, e.g. by doing the 'Family tree' evaluation tutorial or the Watch tutorial.

Open a Graph Tool on Watch Application and Add New for the selected types — further details for the first two are below.

Graph Tool

The first will be our Function object type, just calling a single named function with no parameters.

Property Tool

Let's make sure the Function Name is a legal Java method name by giving it a Value Regex, [a-z]\w* :

Property Tool

The Run relationship will connect the Action to the Function. Let's give it a bold red 20px exclamation mark as its symbol, to show the Action executes the Function. Place a Point Connectable (last on the toolbar) at the bottom left: that's where the lines will run through.

Symbol Editor

On the Graph Tool's Bindings tab, Add a binding for our Run relationship, adding an ActionBody role connecting to an Action, and our Function role connecting to our Function object.

Graph Tool Bindings

Save in the Graph Tool and re-open the diagram, and now we can click Function on the toolbar and click in the diagram to add our 'reset' Function. Then click Run's ! icon on the toolbar and drag from the Action to 'reset' to connect them.

Diagram reset

Automating integration of generated and hand-written code

We want each Function to generate a Java method with an empty body. The Functions will come after the Variable getters and setters:

Generator Variables

newline
foreach .Function
{	subreport '_function' run
}

The _function subreport will output the current Function as a Java method. Use Generator | New... to create the _function generator. Since we want to be able to edit the generated code to add the actual body of the method, we use an MD5 block to produce a leading comment naming this block after the Function name, and a trailing comment giving the MD5 sum of the generated content (initially empty, but where we will add our manual code. And yes, this is a bit of an anti-pattern: ideally we'd keep that code in a separate file. That would actually make life easier, but let's prove a point by taking the hardest case first.).

Generator function

Report '_function'
'	public void ' id '() {
		' md5id id md5block
'		' md5sum
'	}
'
endreport

With our Function generation in place, we need to make sure each place a Function is used in the model calls that function. As each use occurs when a Run relationship is attached to the Function, we use Generator | New... to create a generator called _Run. It navigates along the Function role line to the Function object itself, to output the function's id (i.e. name), then parentheses and semicolon.

Generator Run

Report '_Run'
do ~Function.() {id} '();'
endreport

Finally, for MetaEdit+ to know to merge the model changes with the existing hand-edited code, we change the MERL commands for creating the Java file from write to merge. (It's probably easiest to find the _JavaFile generator if you switch above the list to the Alphabetical view.)

Generator _JavaFile

Trying out the manual code integration

Now we can generate the code for our model, build it and run it. Select the top-level graph in the Graph Browser pane in Eclipse and press the Run Autobuild button. Choose Sporty, press Mode to get to the Stopwatch application, and press Up a couple of times to start and stop the stopwatch. You'll then be back in the Stopped state, seeing the time you measured. For now, pressing Down in the Stopped state will not change the displayed time: it calls the reset method, but that has no body yet, so does nothing.

In Stopwatch.java, edit the reset method to add a line between the leading and trailing MD5 comments, to set stopTime to zero. (Note that we're editing a generated file: normally this is a no-no, but here the MD5 blocks will take care of things, maintaining our manual code but regenerating the rest from the model.)

		setstopTime(new METime());

Eclipse reset

Close the running Sporty and WatchModels. Rebuild the application with Autobuild, and try Sporty again with the Mode, Up, Up, Down steps, and see that Down now does reset the stopwatch time to zero.

Add some new functionality to the model itself, e.g. a Laptime state, Autobuild again and see that the hand-coded line in reset() is maintained.

Summary

So, we took an existing modeling language and its generators, and added a few things:

  1. Extended the modeling language with a new object, relationship and role type, their symbols and rules.
  2. Added the code generation for the new parts of the modeling language.
  3. Allowed the generated code to be manually edited in specific protected regions, which are maintained when the model changes and code is re-generated.

DSM

Ontologies and Domain-Specific Modeling

September 04, 2014 17:06:47 +0300 (EEST)

A little while back a customer asked about the difference between DSM and ontologies, here's my opinion.

A Domain-Specific Modeling language has many things in common with an ontology: classes in a hierarchy, slots and rules about what values they can hold (including instances of other classes), and of course the ability to instantiate the resulting language/ontology. Creating a DSM language also has things in common with creating an ontology: domain analysis, bounding the domain, trade-offs between theoretical accuracy and practical usability, the importance of good names, etc.

However, ontologies and DSM languages differ in how and why they are used, at least for a stereotypical case:

  Ontology DSM
Purpose: Describing something that exists Designing something that will be created
(often automatically from the instance)
Instantiation: Only once, either globally or once by each user Many times by each user, to create many different things
Querying: Often ask questions of the instances of an ontology, like querying a database Rarely queried manually, but instead are often read by generators that produce programs
Cf.: XML schema and instance Programming language grammar and programs
Creation UI: Tree view plus a property sheet;
no possibility for manual layout
Graphical diagram, matrix or table;
layout made by creator of the instance

Programming

D-TDD: Destruction Test Driven Development

January 24, 2013 18:00:25 +0200 (EET)

If you've ever seen a child learn to stack blocks, you'll know that the greatest pleasure isn't derived from the beauty or height of the structure. No: the squeals of joy are reserved for when he knocks it down, and the order of the tower is replaced by the chaos of flying blocks.

Last Friday evening I took an equally constructive approach to work on the MetaEdit+ 5.0 multi-user version. We're at the stage where we have the single user version tested and released, and "the first build that could possibly work" of the multi-user clients, with normal user testing showed no problems. So I set up the server and a couple of clients on my PC, and scripted the clients to bash the server as fast as they could with requests. In each transaction, a client would try to lock and change 10% of the repository objects, then either abandon or commit the transaction.

As that seemed to bubble along quite happily, I started up my laptop too, and used a batch file to start a MetaEdit+ client (from the original PC's disk) and run the same script. And again for a fourth client, whereupon I remembered a PC in the next office was unused, and I knew its MAC address so could start it up with WakeOnLAN. (You really learn to appreciate Remote Desktop Connection, VNC and WakeOnLAN when it's -29°C...)

By the end of the evening, I'd squished a couple of bugs: the more cycles you run, the less chance there is of bugs being able to hide. I'd also progressed to four PCs, running a total of 12 clients. Over the course of the weekend, I occasionally poked my nose into a remote desktop to see how things were doing, and another bug was found (apparently in Windows XP's networking, since it didn't appear on the other platforms; still, easy enough to just retry if it occurred).

At some point I restarted the experiment with the bug fixes in place from the start, to get a consistent set of data. At that point the original repository had grown from 40MB to over 4GB, as each client was creating several times the original amount of data each hour. As I woke up with the 'flu on Monday, the experiment continued in a similar fashion through to my return to work on Thursday. The last session was started Wednesday afternoon, with up to 20 clients, and by the same time Thursday its server had processed 1TB of disk I/O, in under 10 hours of CPU time and only 32MB of memory:

So, what do we learn from this?

  1. Destruction testing is fun! Just as much fun as with the blocks, and even more so: when you catch a bug as it happens, and fix it in the server on the fly, the tumbling client blocks reassemble themselves into the tower.
  2. Destruction testing is necessary. There are some bugs you'll never catch with code inspection, manual testing or unit tests. They might occur only once a year in normal use - and at a customer, where all you get is an error log. By forcing them out of the woodwork with massive destruction testing, you can see them several times, spot the pattern, and confirm a fix.
  3. Destruction testing is easier than ever before. Earlier, the operating system, hardware, or time would be the limiting factor more often than not. Now, normal PCs are reliable and performant enough to keep the focus on what you want to be tested, rather than how to keep enough PCs running long enough to test it.
  4. Destruction testing is not scalability testing. It may stray into that area, but it has a different purpose. The repository used in MetaEdit+ has been tested with hundreds of simultaneous users, so that wasn't in doubt. The point here was to flush out any bugs that had crept in with the new MetaEdit+ and platform versions.
  5. Destruction testing is not bulletproof. There are plenty of bugs that it won't find, but it will find bugs you can't find another way. Since you can't test everything to destruction, concentrate on testing lower-level services called by everything, or just the most common services. Other kinds of testing are better at covering the breadth of functionality.

DSM

Have your language built while you wait, Code Generation 2012

March 08, 2012 15:18:45 +0200 (EET)

From 15.15-16.45 on Thursday 28 March at the Code Generation conference, I'll be leading a new kind of session called "Have your language built while you wait". 15 master craftsmen, representing 11 top language workbench tools, have volunteered their time to build languages for participants' domains:

"Imagine the scene: master craftsmen await, hands poised over mouse and keyboard, ready for you to describe your domain. Together you draft out a prototype language for that domain, seeing it grow as they implement it in their tool. If you want, they might even give you the controls and let you get the feel of things yourself. When the whistle blows after 20 minutes, the work is saved for you and you move on to another craftsman, a different tool, and maybe an entirely different approach. Think of it as high tech speed dating, but without the crushing humiliation."

  • Get a language for your domain, free and made by an expert.
  • Learn about the process of language creation and implementation.
  • Get familiar with different tools and approaches.
  • See your domain from new points of view.

The session is intended for anyone interested in seeing what a language for their domain might look like, or how the language they already have in mind would look in different tools. If you don't have a domain of your own, we'll provide a choice of familiar domains to challenge the master craftsmen with, or you can just sit in and watch the fun.

If you've registered for Code Generation, you can choose which tools you're interested in, and we'll do our best to oblige. Since each master craftsman can only see a few people, places are limited so choose quickly!

Comments

Video and results now online

[Steven Kelly] April 03, 2012 16:25:22 +0300 (EEST)

A video of the session and some screenshots of the results are now online: Have Your Language Built While You Wait. Thanks to all the master craftsmen and participants!

General

Guilty until proved innocent? Flagging unrecognized downloads as malicious

February 27, 2012 19:07:43 +0200 (EET)

Google Chrome's "this file appears malicious" warnings are false and unfounded in too many cases. Similar problems exist with IE, and some anti-virus software. Their tests include two factors that have nothing to do with whether the code is malicious: packed executable, and low number of previous downloads.

Packing an executable is good practice: they take up less space and bandwidth, and are faster to start up from hard disk. Like including some form of software protection or obfuscation, packing may make it harder to recognize or analyse the program, but that does NOT mean it appears malicious.

Software downloads follow the law of the long tail: things like Flash and Adobe Reader installers are frequently encountered, but there is a massive amount of software not commonly used, but which may be very useful to some. Recognizing something as a common download tells you its non-malicious, but not recognizing something does NOT mean it appears malicious.

Both packing and infrequent downloads simply mean that you can't say much about that software. In that case, the principle must be 'innocent until proven guilty'.

If you see someone on the street with a black mask and knife in his hand, he appears malicious; if you see a friend you recognize, he doesn't appear malicious; but if you see someone you don't recognise, and who is mostly obscured by a crowd, you can't go around shouting to everybody that he's malicious.

Comments

Agreed

[John] March 07, 2012 17:32:27 +0200 (EET)

I've recently set up a website and have about six applications with installers created using Inno setup, I could just offer them zipped but I thought it would be nice to create an installer. Chrome tells me that every one of them "Appears Malicious" and presents me with the default option of "Discard", as shown on your site here... What infuriates me is I know they are clean and if it were me visiting someone else's site and that appeared I would just discard and never return because, thanks to this faulty validation process, I have been told that this site hosts malicious software. I checked my site using Google safe browsing diagnostics and, unsurprisingly, it said my site was clean and I've never hosted any malware... Which is a truly god awful contradiction. I suppose it was only a matter of time before they screwed up a perfectly good browser.

Re: Agreed

[Steven Kelly] March 07, 2012 20:39:12 +0200 (EET)

Sorry to hear that, John. For the record, I've seen this problem on Chrome with an installer made with InstallShield, and on IE with InstallShield and even just plain MSI files. Signing the installer or making downloads happen over HTTPS gets around the problem, but since certificates aren't free that's not an option for everyone.

DSM

Code Generation 2011 -- fulfilling the promise of MDD

May 06, 2011 12:22:44 +0300 (EEST)

Code Generation 2011 is coming up fast: less than 3 weeks now! If you haven't already got your ticket, book now -- as I write, there's one discounted ticket left. As in previous years, the lineup is impressive: Ed Merks, Terence Parr, Jos Warmer, Johan den Haan, Pedro Molina and of course experts from MetaCase, Itemis, and Microsoft. It's great to see 10 out of 27 sessions are Experience Reports or Case Studies: Model-Driven Development is an industrial reality, and the media attention comes from real world successes, not academic theory or vendor hype.

Still, MDD has a long way to go to fulfill all its promise, and there are many misunderstandings and prejudices to be corrected. Often the best way for people to learn more is through a discussion, so I was pleased to see Johan den Haan's Goldfish Bowl on "Making Model-Driven Software Development live up to its promises" -- and happy to accept his invitation to kick things off on the topic of "To make MDD successful we need to focus on domain experts and really abstract away from code". Other suggested recipes for MDD's world domination include "marketing", "alignment with programming", and "better education".

Looks like there’s an interesting three-way divide on these MDD issues, depending on the kind of language and who supplies it:

  • vendor-supplied general purpose language (e.g. Rational Rose)
  • vendor-supplied domain-specific language (e.g. Mendix)
  • customer-created domain-specific language (e.g.with MetaEdit+)

The first two are obviously an important distinction but not a black and white one, more of a sliding scale of domain-specificity. And between vendor-supplied and customer-created are variations like vendor-supplied customizable, consultant-supplied etc. (about which more in Juha-Pekka's "Build or Buy" panel at CG2011).

Probably it comes down to three main orthogonal dimensions, domain-specific vs. general purpose, problem domain vs. solution domain, and in-house language ownership vs. outsider-supplied. We could add other dimensions, e.g. text vs. graphics, which is really a sliding scale from “text as characters” through MPS and Visio to “graphical with reusable objects”. Together these dimensions give us a wide and varied space, basically encompassing what gets labelled as MDD. The space is however far from homogenous, and certainly not evenly populated. Instead, there are lots of interesting clusters where the answers to these issues are similar, but radically different from other clusters. In that respect, there's no one recipe for MDD promotion.

For me, there’s no one recipe for MDD practice either: it depends on the focus, scope and size of the project, the abilities of the developers, and the availability of tools. But I’m pretty sure industry behavior as a whole is inefficient in having too generic languages, too much focus on the solution domain, not enough in-house language building, and too much in-house tool building. So I’m happy to preach the good news of companies creating their own problem-domain specific modeling languages with a good language workbench!

DSM

How to build good graphical DSLs

February 21, 2011 17:44:22 +0200 (EET)

Daniel L. Moody (no, not that D L Moody!) has been working for well over a decade on what makes a good graphical language. He brings together previous work in cognitive psychology (which gave us the much-used and much-misunderstood 7±2) with empirical studies of graphical language usability. I've referenced him in some of my talks (e.g. Code Generation 2009 keynote), but I've always been frustrated by the lack of a freely available, in-depth presentation of his research.

That now changes: there's a direct link to his 2009 IEEE Transactions on Software Engineering paper, "The Physics of Notations" in a news item on the web site of his current employer, Ajilon:

"In a nutshell, my paper defines a set of principles for designing cognitively effective visual notations. Visual notations have been used in software engineering since its earliest beginnings, and even before - the first one was designed by Golstine and von Neumann in 1946 - but surprisingly, this is the first time someone has tried to do this."
Daniel says he received a phone call last month from Grady Booch, one of the architects of UML (the industry standard language for software engineering), who is now Chief Scientist at IBM.
"He [Booch] told me he loved the paper and only wished he had this when they designed UML - if so, things could have been very different."

That last comment presumably refers to Moody's testing of UML based on the principles he collected. Predictably, as a black and white language relying on rectangles and solid or dashed lines, UML doesn't do very well in the analysis. You can see the slides from his SLE'08 talk on Evaluating the Visual Syntax of UML, which also form an easier introduction to the principles than the somewhat academic article above (151 references!).

Here's a picture from the slides: see how long it takes you to find the "odd one out" in the three grids below:

Another notation researcher I've referenced frequently, e.g. in the DSM book, is Alan Blackwell, whose PhD thesis showed that pictograms are better than simple geometric symbols or photorealistic bitmaps in graphical language notations. Alan is part of the wider research community of Cognitive Dimensions of Notations, whose site also has a lot to offer the graphical language designer.

Comments

Video of Concrete Syntax Matters presentation from Code Generation 2012

[Steven Kelly] August 15, 2013 17:09:32 +0300 (EEST)

If you're interested in this topic, I gave a tutorial on it at Code Generation 2012, and the video and slides are available on InfoQ: Concrete Syntax Matters.

DSM

Interview on Model Driven Software Network

November 12, 2010 01:31:20 +0200 (EET)

It's always fun to see someone put on the spot... On Monday 15th November at 17:00 GMT, you get the chance to listen in as Angelo Hulshout does just that to me! It's the first of a series of 1 hour interviews run by the Model Driven Software Network, looking at where MDD is, how it got there, and where things are going. We'll also be looking at the practical issues and objections that people run into with MDD.

To listen in, you have to sign up here:
http://www.modeldrivensoftware.net/events/online-interview-with-steven.
Places are limited by the software, so don't wait!

If you have any questions that you'd like Angelo to pose, you can add them as comments at that link. Try to keep them general rather than MetaEdit+ related; if you have tooling questions, our Forums would be a better place.

Edit: If there's anyone out there who doesn't know Angelo, he has a long history in the embedded, modeling and generation communities. In addition to work with Philips, ICT and ASML, he runs his own company, Delphino Consultancy in the Netherlands.

Comments

Recording of interview

[Steven Kelly] November 19, 2010 11:44:05 +0200 (EET)

Here's the recording: it's shown as a video, but in reality there's only audio and a static picture.

MDSN Interview with Steven Kelly from Model Driven Software Network on Vimeo.

DSM

Modeling Wizards keynote

August 05, 2010 15:57:31 +0300 (EEST)

A few Modeling Wizards

I'm privileged to have been invited to give a keynote session at the Modeling Wizards masterclass in Oslo, Sept. 30 -- Oct. 2. As you can see from the pictures, there's an impressive line-up of speakers: Jean Bézivin, Krzysztof Czarnecki, Øystein Haugen and other luminaries from the field of model-driven development.

Unlike other conferences and workshops, this isn't just people submitting their own papers. As the title and line-up maybe reveal, the idea is to offer the best possible training in MDD for the participants. The three-day program offers "a set of carefully selected lectures dealing with various aspects of modeling and with a particular focus on domain-specific languages. The objective is to provide each attendee with sufficient information to understand the main issues and challenges in the use of modeling and domain-specific languages, and also to have a clear picture of the most recent advances in the field."

One thing I'm particularly happy to see is a mini-project running each afternoon, where participants will get the chance to put what they are learning into practice, with a helping hand from the speakers. I'm a big believer in the master craftsman - apprentice mode of learning, and have benefitted greatly from it myself over the years. To ensure the personal attention necessary, places are limited -- so sign up now! The price of around 887€ includes accommodation and all meals for the three days, which compares very favorably with any other training I've seen. With the timing just before MODELS 2010, you can even get two events for the price of one set of air fares!