Thursday, November 26, 2009

Readable vs Elegant?

I've been thinking about this for some time but there seems to be a contradiction within the software development community, an internal struggle between being clever and superior and a wanting for things to be clear but succinct.

At DevDays in London, Joel Spolsky showed a code snippet of how you would copy a string in C.

It was something like :
while (*s++ = *t++);
to the untrained this may look like a half finished effort, it isn't and even though the first time I saw it I thought WTF. A second glance and you can see that amongst the terseness it is actually doing something utilising pointers.

So I guess that I would call this elegant code and even though (from my pointerless point of view) it took a second glance I would call this readable code. This is probably a very good example of Elegant yet Readable. We should all strive to write like this but there are cases where we go wrong.

Elegant but not Readable

Above is a 1989 entry for the International Obfuscated C Contest, confusingly it prints e. You cannot deny a lot of love has gone into making in unreadable. I know that's the point but I feel sometimes some developers go out of their way to out smart their peers. Often the author will protest that their peers should know what the code is doing, the implication is that they are superior to their idiot counterparts. It is the ultimate in geek posturing and is done at the expense of maintainability and probably team harmony.

Readable but Inelegant

while (*t != 0) {
    *s = *t;
*s = *t;
I just looked up the antonym of elegant there because I didn't want to use inelegant. After looking at the options I stuck for inelegant but I thought that two of the other suggestions were worth considering.
graceless and unpolished
This code often comes from a novice or perhaps an intermediate user of a particular language someone who is comfortable enough to get by but by no means a master in it.

The code example above is the doing exactly the same thing the original example but is more verbose. At the same time it is perfectly readable but knowing that what you can do in 7 odd lines, does it become graceless and unpolished?

Is Elegant better?

I think when someone attempts to write elegant code there are three levels the code can attain. These are defined by the initial reaction of the reader.

  1. Too much: "Woah wtf is he doing here!?"
  2. Just right: "Ooh that's neat."
  3. Too wrong: "Err this builds but that's it."
Elegance should be harnessing the idioms of the language but when it becomes a form of obfuscation that's when the problems occurs. Yes you may scare the newcomer by using an advanced feature but as long as the intent is clear I see no problem in harnessing all the features of a language. Those features have been designed so your code is more expressive in less lines of code. Provided the language design is good we should take advantage of them.


I decided to write this blog post as I wanted to clarify my thoughts on the matter, I think I've come to the conclusion you should make you code readable at all times but at the same time you can be elegant with it. In fact elegance is something you should strive towards as I believe elegant code shows you know your tools well. There doesn't have to be a choice between readable or elegant. The choice you should make is readable and elegant.


Martin said...

Good points. I tend to think of elegant code as code that is both clear and concise - to me that is elegant. Therefore, one langauge to the next allows for a different degree of elegance. (pretty hard to be elegant in assembly language, compared with C#)

I wrote about this on my blog if you're interested.

Food for thought, good post :)


Mark van Harmelen said...

I think elegant is dependent on the eye of the beholder, mostly on their language sophistication ; for example I couldn't see anything other than the while and pointer loop as being elegant. Equally I think it is more readable than the alternatives.

As for maintainability I think the use of a known language idiom helps the maintainability of the surrounding code by cutting down the volume of the surrounding code.

But it in itself not maintainable for a C beginner, and, caveats within caveats, in fact as it stands its not really maintainable:
while (*s++ = *t++);
what's the problem? We should have
while (*dest++ = *src++) {
// empty body

elegant and maintainable, at least for C, but not for C++