January 2005

« December 2004 | Main Index | Archives | February 2005 »


Joseph Ottinger:

I don't know Python yet... so I don't sit around wishing Java had features that I don't know how to use, nor do I routinely encounter problems in Java that distress me over their lack of solution. It's usually my knowledge that's at fault, after all, not Java's lack of solution. Why would I blame the language?

The Pragmatic Programmers:

Learn at least one new [programming] language every year. Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut.

This is valuable advice.

Thanks to Alan Turing, we know that computationally speaking, all programming languages are equivalent. If this meant they were all practically equivalent, we'd still be programming in Assembler. We're not. Instead, the history of programming has been a long procession of different languages, some of which are still going strong, and others that have withered or been superceded.

For a general purpose programming language to gain traction, it has to solve some set of problems better than competing languages. This is true of even commonly vilified languages like Basic and COBOL (or for that matter, Java). No language emerges in a vacuum: for any language to gain a following of programmers, it must attract them from competing languages by offering them something that they need.

(Paul Graham has a presumably slightly tongue-in-cheek but quite apt characterisation of languages based on what aspects of previous languages they 'fix')

Computational equivalence means that (ignoring for the moment practical matters like being able to address specific hardware), there are no problems you can solve in language A that can't be solved in language B. Language design, however, means that how A and B solve problems can be markedly different. Without exposure to other languages, it's far too easy to be blind to the fact that just because your language of choice can solve a problem, it may not solve it in the best way.

Take, for example, the canonical example of a QuickSort in Haskell:

  sort []           = []
  sort (pivot:rest) = sort [y | y <- rest, y < pivot]
                      ++ [pivot] ++ 
                      sort [y | y <- rest, y >=pivot]

If you understand Haskell, it's pretty clear that this is more elegant and expressive than the Java alternative. If you don't understand Haskell, you're more likely to have a "what the?" moment, and go back to hacking Java.

Having said that, I haven't ever programmed in Haskell (I coded in Miranda in first-year Computer Science, but haven't ever used it since). Nor, I suspect, will I soon. I contend, however, that knowing how different languages solve problems makes you a better programmer in any language. Some techniques can be adapted between languages, or can be embedded in a "little language" tailored to a particular problem domain. Even at the simplest level, knowing where your language of choice is limited helps you work around those limitations more efficiently.

The danger of learning new languages, though, is that each one increases the chance that you'll turn into one of those Internet whiners (like myself) for whom the best language for any job always seems to be the one you don't get to program in often enough to see its flaws close up.

Death by Email

  • 12:43 AM

I had nothing much else to do this afternoon, so I installed the latest Mac OS X Tiger seed on my home iMac. Mentioning this probably violates some NDA or other, but I figure so long as I don't divulge anything that Steve Jobs hasn't already demonstrated a thousand times, I should be safe.

OS X's Mail client has been spotlight-ised, of course, with smart folders and impressively fast searching through my 300Mb or so of archived mail1.

One smart mailbox that is included by default is a collection of all your unread messages across all your mail folders. Turning on Mail for the first time, I was greeted with the news that I had 55,000 unread messages.

Needless to say, in the time it would take me to even sort through 55,000 messages and intelligently throw away the ones I wasn't going to read, I'd have accumulated 50,000 more. So I created another smart mailbox of all unread mail that was more than a week old, and with a short, guilty mouse-click, marked them all as having been read.

Then, after making a cup of tea, I went through the rest. Mail is now happily reporting that not a single message of my entire mail archive is unread. I suspect that's untrue for at least 95% of the messages.

The problem is mailing-lists. I'm genuinely interested in the goings-on of the ruby-lang mailing-list, but at over a hundred messages a day, it's simply impossible to keep up with it. I'm genuinely interested in firewall-wizards, but even though it only sees 10-20 messages on a busy day, I'd probably rather read 20 more mails from the Ruby list.

And so on. Before you know it, you've got 55,000 unread messages.

Mailing-lists suck. So many projects rely on mailing-lists, even to the point of requiring you to subscribe to a list before you can communicate a bug, submit a patch or even provide feedback. And every list is mental overhead that you just don't need if you're planning on spending any time not reading email.

And don't tell me how RSS is going to save me from email. I have 550 unread articles waiting for me in NetNewsWire.

The best cure for this particular malaise that I've encountered was kernel-traffic, a weekly newsletter summarising the significant goings-on of the linux-kernel mailing-list. Unfortunately, kernel-traffic is an exception that I've never seen translated effectively to another list: it requires a rare level of commitment from an individual editor, and an even rarer talent for summarisation.

One of the more convincing arguments for wikis has been that they offer projects an escape from email Hell. Conversations on a wiki almost inevitably lend themselves to summarisation as the site's (usually self-appointed) WikiGnomes point people to previous discussions, and act as a distributed force to clean up threads into pages. These post-discussion pages then become a natural part of the project's documentation.

While I was writing this post, 8 new messages arrived in my ruby-lang-new folder. I didn't have time to read them.

1 My work mailboxes are bigger, possibly by an order of magnitude, but testing against them would involve upgrading my Powerbook to Tiger. I don't really want to put a pre-release operating system on the machine I do all my coding on.

Found this entry of "things Java programmers should keep in mind moving to Python" via my increasingly spam-polluted referrer logs. (Give up, guys, it's blocked by robots.txt, so no legitimate search engine is going to pick it up.)

Anyway, by explaining how the other half lives, this quote sums up my philosophical objection to, but grudging acceptance of the proliferation of XML configuration files in Java.

XML is not the answer. It is not even the question... This is a different situation than in Java, because compared to Java code, XML is agile and flexible. Compared to Python code, XML is a boat anchor, a ball and chain. In Python, XML is something you use for interoperability, not your core functionality, because you simply don't need it for that. In Java, XML can be your savior because it lets you implement domain-specific languages and increase the flexibility of your application "without coding".... But in Python, more often than not, code is easier to write than XML.

The thumbnails link to larger images. I was disappointed by the disco-ball at first, but it's quite fun now.

Bridge under yellow and green light

Bridge under red and blue light