May 03 2007

Illiterate programming

Programs must be written for people to read, and only incidentally for machines to execute.

The above citation from Harold Abelson and Gerald Jay Sussman's Structure and Interpretation of Computer Programs encapsulates the growing trend of what has for some time now been coined as Literate Programming. Programming has come a long way since the days of Assembler in terms of human-friendliness, but, as with many other programming best practices making it into the mainstream, code literacy is often misunderstood and misused.

I have to say at this point that I do not one hundred percent agree with the "programs are meant to be read by people" notion. That is because programs are written by and meant to be understood by a very narrow subset of People: Programmers.

Naively making code read like English hides many dangers that could result in reducing productivity, making software less efficient or introducing bugs. That is, of course, not meant to be interpreted as name your methods chk_str_ptr() , more like approach with caution and make your code meaningful to your peers (the other programmers) instead of someone who has never seen and is unlikely to ever see anything resembling code.

It is safe to assume that all developers are competent in their native tongue. Because writing code that reads like a spoken language is easier than writing good code, many developers tend to get carried away, shifting their main focus to that aspect of their work.

Syntactic sugar (not the good kind) often boils down to wrapping code that does the actual work. This, if not performed with great attention, usually results to adding a few extra layers of complexity for anyone trying to figure out what the code does. The moment something like submit_the_payment_and_send_a_message_to_the_customer (spot the anti-pattern here?) somehow doesn't send messages to the customer, while making a couple of redundant roundtrips to the database, we're in trouble.

Expressive code does not necessarily share that many traits with what is considered to be expressive in a spoken language. Take Ruby, arguably one of the most expressive programming languages, for instance. What makes Ruby expressive is how it will enable a programmer to write code like conditions ||= parameters.delete_if { |p| Customer.respond_to?(p) }. This will probably not mean a lot to the average English speaker, it is however one of the reasons Ruby programmers are so passionate about the language.

On the flip-side, Rails, one of the most semantically challenging APIs, suffers some performance issues, largely due to the efforts to make the API read and behave the way it does.

Decorating code with the sole intention of making it resemble a spoken language violates the principle of Simplicity. Paul Graham describes this symptom very well in Taste for Makers:

It seems strange to have to emphasize simplicity. You'd think simple would be the default. Ornate is more work. But something seems to come over people when they try to be creative. [...] When you're forced to be simple, you're forced to face the real problem. When you can't deliver ornament, you have to deliver substance.

When coding, it pays to remember that good code primarily means code that is as bug free, efficient, scalable and maintainable as possible. Any other improvement must be sought after, but not if it compromises any of these core values.

Elegant is the code that presents a simple solution to a complex problem, not the one that hides complexity behind a simplistic fa├žade.