Too Much Code

Not enough cohesion

Part 2: Languages and the Lesser-Skilled Developer

My last post ended with an assertion: we need a language with the best of Haskell in a more accessible form. This leads to an old debate. After all, building good software requires tremendous skill. How can we make progress if we tailor it to the weakest practitioners? Bjarne Stroustrup made this point well:
The idea of programming as a semiskilled task, practiced by people with a few months’ training, is dangerous. We wouldn’t tolerate plumbers or accountants that poorly educated. We don’t have as an aim that architecture (of buildings) and engineering (of bridges and trains) should become more accessible to people with progressively less training. Indeed, one serious problem is that currently, too many software developers are undereducated and undertrained.
Stroupstrup is right, of course. Too many developers are undereducated; we should demand greater skill. However, this doesn’t change the fact that language adoption for a given shop has as much to do with politics as technical merit. Businesses have a perceived need to hire armies of developers to quickly write bad code and bad software. We’ll be asking ”WTF?” for a long time to come.

The problem is highly skilled developers are often forced to use the languages accessible to their less competent colleagues. Browse the forums at Reddit and you’ll find lots of developers coding C# or Java by day and Haskell or Lisp by night. In short, a language must be usable by lesser-skilled developers so high-skilled developers have more opportunities to use it. Ruby is a great example of this in action – building a quick and dirty web application is trivial, but the language still offers powerful constructs such as closures.

Battling the Hack
Anyone who has written software for a couple years has come across the Nasty Hack – what should have been a simple piece of code made horribly complex, requiring an alignment of planets to work. Languages such as Haskell have the laudable goal of preventing nasty hacks by restricting what can be done in a given context. Sadly, good design often takes second place to deadlines – and a language that has the appearance of slowing development won’t get far, even if it offers a net gain.

Even a language that prevents some classes of nasty hacks will allow others. No language will free us from bad code altogether. Even worse, languages that free us from large classes of bad code have trouble getting adopted because businesses indirectly want to hack. This has depressing implications: the nasty hack is here to stay, and languages attempting to eliminate it will struggle to find widespread adoption. Our only hope is a fundamental cultural change in the way most organizations build software.

There is nothing I want to see more than this cultural shift. Maybe some day the market will get so sick of bad software it will force change. Consumers might realize great software is possible, as shown by a few innovative companies. Other companies might finally delay entry to a market, knowing a buggy solution will be rejected. The lesser-skilled developer might be forced to improve or leave the field.

However, while attempting to change the culture we still need to innovate under the current constraints. This means it must be easy to write quick and dirty code in a widely adopted language. So I submit a requirement for our new language:
A language should encourage good code – but make quick and dirty code possible.
Today languages like Ruby and Python are probably the closest to the mark. Inexperienced developers can quickly get code working, and more advanced developers have access to powerful features drawn from the functional world. However, both of these languages have shortcomings when compared to Haskell. Incorrect code can lead to unpredictable behavior, and poorly designed code can lead to a state space too big for any human to understand. Specifically, they do not offer a tractable solution to concurrency and composability (pdf).

In my next post I will attempt to outline a language concept drawing from the best of Ruby, Haskell, and other sources.

(Edit: fix typo)