Tuesday, April 22, 2008

Why A Runtime User Interface Generator

I was recently asked why Metawidget works at runtime, instead of pre-compiling and statically outputting generated code. There are two reasons.

Easier to Maintain

I think people like static code generators because they give the illusion of being productive: you click a few buttons and bam! you suddenly have this whole app with mountains of code written for you, all ready to go.

But I do think it's an illusion. Let's look at what, typically, you have to do with a piece of code:
  • write it
  • debug it
  • unit test it
  • update it
  • document it
  • hand it over

Whilst code generators might ease the first one (write) they're no help with the third (unit test) and they actually make the other four much worse. This is because the code they generate is usually quite poor (it being generated by generic algorithms) and because nobody, not even the developer who runs the tool, initially understands the code it produces.

Runtime generators, on the other hand, are great when it comes to updating, documenting and handing over, because a) they haven't produced a mountain of code for someone to trawl through and b) documentation on how the runtime generation process works is normally very good (eg. it's in the generator's user manual).

So I'd much prefer a runtime approach to a compile-time one. If you compare systems like JPA to those that pre-generate mountains of SELECT/INSERT/DELETE stored procedures I'm sure you'd agree.

More Powerful

There are lots of important properties of a system and the relationships between its parts that are only discernable at runtime, not statically at compile-time.

For example, the Address Book sample application adapts its screens dynamically at runtime depending on whether the incoming object is a PersonalContact or a BusinessContact. And there are @FacesNotHiddenInRole annotations that modify a UI based on the currently logged-in user.

Finally, if you're inspecting 'live' objects (as opposed to source files) you can automatically do a lot of the binding between UI and application layer, further reducing all that boilerplate code.