The Skeptical Methodologist

Software, Rants and Management

Tying your hands behind your back and loving it

Small post today, but a thought.

Sometimes, for many problems, the best way to approach the programmatic solution is to code/specify the solution in the language you wish you had, and then implement that language.  This is the DSL approach to programming.  The best poster case for this sort of programming is Lisp and Forth, primarily because they are so easily amenable to the meta-programming required.

As a side note, it’s ironic that the DSL approach to programming isn’t more widely adopted in corporate and engineering culture.  It’s just about every other day some new company is promising a new way to codify system requirements to help in the software engineering process.  Seems like the solution they’re approaching asymptotically in the ‘enterprise’ field is to code up user requirements in a programming language itself.  But I digress.

DSL’s are incredibly useful from a usability perspective – frequently, a domain specific declarative language can specify something in far fewer lines than the equivalent fully fledged programming language can.  I recall a presentation I saw that, unfortunately, I don’t have the time to link to, that described Adobe Photoshop’s code being 90% publisher-subscriber patterns trying to run an overall MVC such that any new command you use is instantly reflected in the underlying picture.  That means, as a good estimate, 90% of their bugs exist in that code too.  The speaker then explained a small, declarative language he developed to capture most of the same usage of Photoshop.  The code was far smaller, maintainable and readable.

But, a frequently overlooked side of DSL’s is that they limit you.  In many cases, DSL’s are not Turing-Complete, meaning that there are tasks that any particular DSL simply can’t solve.  Believe it or not, this is the best thing they have going for them, though.  A language that’s Turing-Complete can express any computable algorithm, but it also suffers from some drawbacks, not the least of which is the Halting Problem.  The idea is that, for any Turing Complete language, one can never prove whether any arbitrary program halts in that language or not.  In layman’s terms, we can’t detect infinite loops.  That’s not all, though, as many problems can be reformulated in terms of the Halting Problem, meaning that they too are undecidable.

Do we need a Turing Complete language, though, to describe a GUI?  Or a MVC framework?  For most of our work, we can sacrifice a tiny bit of power to step back into weaker computation mechanisms.  In fact, when you really think about it, the only problem we really need a Turing Complete language to describe is the problem of what non-Turing Complete language we really ought to be using.  I’ll get back to this in a second.

If a language is not Turing Complete, that means we can prove far more useful things written in that language.  That means program proving mechanisms become a much more useful way to eliminate and track down bugs and defects.  None of this is to say that we can’t prove a lot , or at least, assume a lot about programs we write today – it’s very impressive just how far static analysis can go based mostly on heuristics.  But the fact of the matter is, in simpler constructs, we can prove far more.  And when I say prove, I mean prove. Unit tests, while very valuable for defect detection and development, can never prove bugs absence, just their existence.  Via proofs, in a language that is limited enough that can be constrained in this way, we can prove the absence of certain bugs.

What does this mean insofar as development is concerned?  It means that perhaps, once size should not fit all.  It means that we can tie our hands behind our back with DSL’s and love it, as long as we have a variety of DSL’s to do every small job for us.  We now have constrained where defects can occur to the Turing Complete languages we must use to implement our DSL’s and the glue code we must also write to have our DSL’s interact.  That’s what I was talking about before – perhaps the best role for our powerful, Turing complete languages is not to solve problems, but to describe less powerful languages that solve those problems and also prove things about those languages.

A language for GUI’s, a language for events, a language for this and that.  We already are used to this sort of thing, we just call these sorts of things libraries.  Learning a new DSL, since it does not have to be any where near as expressive as a fully fledged programming language, need not be any more difficult than learning any new API.  Using this approach to development, not only can we begin to reap the huge productivity benefits of using declarative, specific languages to solve specific problems, but also reap the huge quality benefits of relying more on automated proving mechanisms rather than just tests.  This quality benefit itself turns into a boost in productivity, since most of our time gets caught up in chasing down defects anyway.

This sort of separation of concerns can already be seen in a language like Haskell.  While Haskell has not demarcated a certain part of it’s core vocabulary as Turing Complete and another part as somehow less powerful, it has taken the important step to separate pure computation from more dangerous things like I/O via it’s monad mechanism.  As an example, then, I imagine it’d be far easier to prove something about pure functional Haskell code than even in another functional language.  This drastically reduces the amount of program testing and manual verification we humans have to do, and the language already lets us know where to focus our effort – state driven, I/O code.  This sort of separation of concerns can continue such that each time we delve into a specific way to solve a known problem, we already have a huge safety net ensuring quality, even before tests.  Combine this with the expressiveness of the same specific language on the specific problem, usually reducing the amount of code by as much as a factor of ten, and you can almost see, if not a silver bullet, a good, solid lead cannon ball for development and developers.


December 14, 2008 - Posted by | Software Methodologies

No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: