Ayende @ Rahien

Refunds available at head office

Understanding Bad Code

Frans' contribution to the conversation about maintainable code deserve its own post, but I would like to mention this part in particular:

you will not [understand the code]. Not now, not ever. And not only you, but everyone out there who writes code, thus that includes me as well, will not be able to read code and understand it immediately.

You know what? That is not limited to bad code. I had hard time grokking good code bases, simply because of their size and complexity (NHibernate and Windsor comes to mind). Other code bases are as large, but they have easier approachability, probably because they are dealing with less complex domain an tend to have a wide coverage rather than deep (MonoRail comes to mind).

A while ago I was involved with an effort to migrate an ancient system to SQL Server 2005. The system compromised of over 100,000 lines of code, spread over some thousands of files scattered randomly in a case sensitive file system (you can guess why this is significant). The code base was about 85% SQL and 15% bash shell scripts. The database in question was a core system and contained slightly over 4,000 tables. One of the core tables was called tmp1_PlcyDma and was used to do business critical processing. That code base took data driven code generation to a level I have never seen before. I gave up trying to track down 7(!) levels of code->generating code->execute code->generating code->rinse->repeat

To say that the code base was bad is quite an understatement. To mention that the only place where I could run the code was by using a telnet console into a test environment that was not identical to production is only the start. I could mention no debugging, runtime of ~5 hours, test time of ~3 hours, etc. The code grew organically over a ten years period and you could track the developer progress from merely annoying to criminally insane (he invented his own group by construct, using triple nested cursors and syntax so obscure that even the DBA that worked with the system for the last 5 years had no idea what was going on).

Perhaps the thing that I remember most from this project that we had a bug that kept two people hunting after it for three weeks. The issue was a missing ';'. Oh, and the criteria for success in this project was successful migration, with bug-per-bug compatibility, and no one really knew what it did, including the authors(!).

But, you know what, after a month or so of looking at the code, it got to the point where I could look at something like pc_cl_mn.sql and know that it would contains the monthly policy calculation, and that this piece of code was doing joins manually via cursors again, that plcy_tr_tmp.sql was the "indexes priming" script, etc, etc.

The code was still a horror, but once you understood that the authors of this code had a... "special" way of looking at databases, you got to the point where you could get the point of the code in an hour instead of a day, and then move that to a saner approach.

So, what does this horrifying story has to do with Frans' point above?

The premise that you can read and understand code immediately is highly dependant on what you are familiar with. I know of no one that can just sit in front of an unfamiliar  code base and start producing value within the first ten minutes. But on a good code base, you should be able to be able to start producing value very quickly.

Comments

Mr_Goo
06/18/2007 09:50 PM by
Mr_Goo

Yeah I was making this point the other day on this blog or another. I called it TTS for The Total Mess.

All this and that super uber stuff is cool to talk about, but for real world apps it all turns into goo at some point. At that point being an employee SUCKS because they'll never promote you because you're the only one know knows the system.

On the other hand, being a consultant is GREAT because they (your boss) already knows how hosed he is and they just pay you for two weeks to hunt down a single bug.

Personally, I love the goo baby!

Frans Bouma
06/19/2007 08:05 AM by
Frans Bouma

I wasn't talking about bad code in particular, just any code. The problem is that if you have a piece of code and you want to UNDERSTAND every detail of it (you have to, you can't ignore little details, it will bite you sooner or later if yo do), you effectively have to run it and see what every statement does: which state it changes and what the result is of that state change.

When a human reads program code and tries to understand it, the human will make assumptions at every line what that line does, what the effects are of that line, so the NEXT line's effect can be understood as well.

Your point, that understanding a piece of code after you're familiar with the code base isn't correct: if it would, you wouldn't create any bug in any software you're writing, as you're always familiar with the code you just wrote, right? :)

Never over-estimate what a human understands from code, as it's fairly limited what a human understands from program code, simply because just looking at code isn't revealing anything to the reader unless you 'interpret' it line by line in your head and that's precisely where it goes wrong.

That's not a bad thing, it's just a fact of life and because of that, a human has to take that into account when software is written. This can get tedious at some point, but it's essential.

Another mistake, which is a bit hidden between the lines of the article, is that code isn't falling out of the sky: it's the result of a process. Assuming that the result of the process is enough to understand every step taken in that process is IMHO a mistake: there's no proof that by looking at code you can see the process, the steps taken, the reasoning followed etc, on the contrary. (we all run into the fact that code isn't reflecting the whole process when we have to go back to some code we wrote some time ago to refactor it. No-one can read that code and instantly remember EVERY detail of the process that resulted in that code, a human needs help with that. Which is natural and a fact of life.

Now, it would be great if we all stop being so stubborn and simply admit that humans aren't as good in reading code as we think we are and thus that we should focus on tools which help us along the way to overcome that limitation. Only than we really will make progress in the quality of software engineering.

Travis Laborde
06/19/2007 11:43 AM by
Travis Laborde

It's good to hear that it's not just me. I think I'm a bit slower than most though - at getting comfortable with an alien codebase.

I once hired a woman named Uma who was absolutely GREAT at this. She could sit down in front of code she'd never seen before and within a couple of hours she was comfortable with making changes, and not breaking things.

I'd say she made me look bad - except that of course since I hired her I looked good in that sense :)

Joseph D. Gutierrez
06/20/2007 02:21 AM by
Joseph D. Gutierrez

LOL. The code base I inherited because the company changed coasts, was the same exact one that as a field service I would request bug fixes or adding functionality. So it came down to me being the Rosetta Stone for this code. LOL.

Comments have been closed on this topic.