2007-07-25

The shoemaker's children have no shoes.

With all the research and all the effort poured into human interface design out there, and with the ever-increasing number of actually usable applications available, why is it that software developers are left out in the cold with seriously crappy tools to do their work?

I ask this question in all seriousness, knowing that the strongly reactionary streak that underlies most software developer thought is going to result in heaped abuse. (There I go again, imagining that people actually read this blog!) Just to ramp up said expected abuse, let me make this clear:

Software. Development. Tools. Suck.
All of them.
Every last one of them.
No exceptions.


Here I'm not even talking my language bigotry which has me laughing scornfully at those who think that Java is a pretty neat language to work in. This is not that rant. This is a rant about the tools that support the programming languages. Any of them.

Despite programming being increasingly complex as we get more and more powerful computers and more and more capable software, the nature of software development hasn't really changed. We still, effectively, program these multi-faceted, multi-dimensional creations we call software with one-dimensional streams of characters. We have large text files with long strings curled up inside them in ways which, if properly formatted, are sort of simulations of two-dimensional constructs (with some languages—Python and Haskell, for example—even mandating these structures with layout rules). These large files are the only unit of organization we really have. Some languages go so far as to only really simulate this level of organization and require programmers to bodily insert (#include, for example) any used files to generate, at compile time, one enormous file that gets compiled. The rest give us some slightly more civilized approaches to things. Haskell, for example, has its .hi files which are automatically generated on compilation and which therefore don't require interfaces to be explicitly defined in two different places. You just list the symbols you're going to expose to the outside world and the compiler annotates them with type information. It's a step up, but not a big one. You're still maintaining files and worrying about minutiae in the process.

Lately I've been bitten by the literate programming bug. I'm even (slowly) contributing to the LiteratePrograms Wiki, partially as a way of practising the techniques and partially as a way of furthering my Haskell education. (I find that explaining things helps me learn them, you see.) I'm also, as a "weekender job" (and a break from my weekday work over the summer) writing a self-tangling literate programming system for Ruby allowing people to use the literate style and execute it directly, as well as tangling it manually (to get pure Ruby output) and weaving it into documentation. (I have a working prototype of the self-executing system already after a day's work and will post the whole thing in gory detail here when the first version is completed.) The ideas behind literate programming have really captured my imagination – and yet still leave me unfulfilled.

Unfulfilled, you see, because the tools still suck. It highlights what's wrong with literate programming as well – in the end it's still just a long, one-dimensional string of characters. In-band signalling (a permanent nightmare for any real work!) is used to switch between documentation and code. Mark-up is used to modify content and in general it's a mess. The output is nicer and a proper literate programming environment (unlike, say, Haskell's pseudo-literate .lhs files) makes it easier to keep documentation and code organized and coherent, but it's not good.

So here's what I want.

I want a literate programming tool, first and foremost. I want to be able to pair documentation with code in an order that makes sense for reading the code without worrying about which order things are defined in and without spamming the reader with funky little details that obscure the overall structure. (Error handling code is particularly guilty of this.) When I write in the documentation side, I want it to be like a word processor – or like a text editor suited to whatever markup I choose to use. (The key here is choice. Some people like working with, say, LaTeX, others with X/HTML and still others with a WYSIWYG system. Accommodate them all.) When I write code snippets, I want it syntax-highlighted with keyword lookup and expansion, easy reference to library documentation and I want these capabilities easily edited (so that I can add, say, new keywords or new library members). I should be able to write the code "out of sequence" and, here's the key, easily edit the sequence (graphically or textually – again the user's choice!) so that the system generates the right code in the right order at compilation and/or runtime. And, of course, with the press of a button, I want nicely-formatted documentation—user's guide, reference, design documentation, etc.—generated and printed or viewed. (This implies, incidentally, that the documentation/code pairing may have multiple dimensions on its own. The code could be threaded differently through the design documentation than it is through the reference manual, for example.)

I'd like this all to happen in a development environment that conforms to the human interface standards set down for the platform this is all running on. A Windows version should feel like a Windows application and use Windows standards for the GUI. The same applies to GNOME, KDE, CUA, anything. The application should feel native so that a GNOME programmer, say, doesn't feel like they're being forced into Mac thinking while developing their software.

And that's just the minimal demands list. Even bigger on the "pie in the sky" list is integrated, multi-lingual debugging. I'd like to be able to launch my program, even if it's built from multiple languages, and step through my code where the system displays the snippets as they execute and, optionally, pairs them with the documentation surrounding them. I should be able, in short, to debug the code as tangled or as untangled without worrying as I step from one language's executable to another. If I make a Ruby extension, for example, I should be able to step through the Ruby code as well as the underlying C code implementing key functionality. Hell, I should be able to step through standard libraries (if debugging information is available for them) if I click the right switch!

Of course I will never see any of this because, as the old saying goes, well just look at the title and weep.

0 comments: