Hacker News new | ask | show | jobs
by Mintz 6169 days ago
The irony of you saying "almost everything I ever inherited was crap in one way or another" is that somebody probably said the exact same thing about your code. I bet you write amazing code, but when given a choice, programmers would rather have the joy of creating their own code than trying to interpret someone else's.
3 comments

Let me try to sketch how bad it can get:

In the mid 80's I worked for a game company for about a year (Aackosoft, flightdeck, indy 500 on the Atari) and I inherited a project from another programmer. After reading the code for a couple of days I realized that he'd been planning his 'exit' for a considerable time. The could would assemble (the 68k part) and compile (the C part) but other than that you couldn't make heads or tails of it.

Every variable was named after a vegetable, a fruit or a plant and every subroutine after a famous person.

It took quite a while just to get things back to self documenting names, after that another month or so to restructure it to the point where it started to do what it was intended to do.

There would indeed have been much joy in writing it again, but there was just as much joy in figuring it out and getting it to work.

could = code, sorry...

and no, I'm not making this up!

When it comes to maintaining code, I believe there are 2 kinds of crap: subjective (I don't like it) and objective (it's crap because of these 14 specific reasons).

You're probably right about people who inherit my code. I know, when they've whined about it, I confronted them. "Please show me exactly what's wrong with it. What are your specific complaints about violations?" I rarely got an objective answer. It was usually something about formatting, indenting, variable names too long, variable names too short, I'm use to it the way we did it (wrongly) at XYZ Co., something like that.

True crap can be objectively identified by a violation such as:

- variables named so that no one except King Tut could possibly figure out what they are

- the same variables used for different purpose at the same time, usually in nested recursions

- variables named with 1 or 2 characters

- unassigned variables

- variables initiated when they shouldn't be

- division by zero

- single entry, multiple exit (heavily maintained so that now outlying cases skip critical logic)

- the same code in multiple places (only some of it maintained so that outlying cases skip critical logic)

- endless recursions (for outlying cases only, naturally)

- comments that don't agree with the code

- data base tables with no definitions either in the schema or any code (my new favorite)

I could go on and on, but you kinda get the picture. I wonder how many readers here have posted crap like this on their "wall of shame" at one time or another. It's funny the first 2^n times. Not so much fun anymore.

Those are technical issues. The truly most nightmarish software to inherit is one that shouldn't have been writen to begin with: software made by people who either lack the programming skills, or the domain knowledge. Nothing worse than an accountant-turned-DBA's perl, or a system's programmer that just left you an steaming pile of MFC GUI. Worst of all, the person responsible for the mess is not long gone and forgotten, quite the contrary, he has been promoted through and he is now responsible for interviewing you to polish his brown magnum opus.

I breath a sigh of relief whenever Microsoft breaks and old DLL's compatibility: when you can't push through for an upgrade, pray for Redmond to force it.

[Update:

``The hardware-specific accounting package''

This one is truly the "winar": plain-jane boring software that for some goddamn reason depends on that old Hayes modem, or this matrix printer. I have been hired to do this shit so often it's not even funny; it tends to sneak past the initial discussions. You tick off "GUI" and "ODBC" and you're on your way to start hacking, making a mental note about "ability to print". What you don't know is that, not only do they want to convert the old Access package to an intranet web app, but they also want it to print receipts using the "receipt printer" -- a custom made piece of pain that uses the parallel port for data, the serial for control, and two RJ45s to whistle the Danish national anthem on error. FUCK!]

Now I can't sleep (why did we have to talk about bad code?)

``The Windows 3.1 Guru''

1) That guy who knew too much about Windows 3.1 internals and never thought this newfangled "Windows for Workgroups" or "95" would never take off. Thank you, sir. Treating obaque structures for the unsigned chars they are has never posed a problem for me. All the documentation I needed was in those 4 pages of macros you left me (completely unnecessary, given the clarity of their octal values, btw) Indeed, 10 years later, the low nibble of the AL register held an integer index into your very own "stash area" just below the PSP (task_struct for linux weenies) where you kept all the open file handles. Clever of you, reusing every bit of the process memory, specially the unused parts of the MS DOS header format. (long story about this destructive log-rotate elided)

Your share custody of this award with Mr. EE.

2) Mr. Electrical Engineer, how can I forget you? We all know it's all signals and gates down there, so, yeah, it was refreshing to see them again! I can't believe you rolled your own signal-driven layer on top of the Win32 message system. The ordering system couldn't have been done any other way. Looking at your code put a bar over my head, sir, you have asserted me. And to be honest, Visual C++ needed your linguistic extensions; we all know, code runs faster when it looks more and more like Fortran.

These would be richly funny if they were not so entirely true.
These are awesome.
You had me at "steaming pile of MFC GUI."
Some of these "violations" are good ideas in some contexts. Tom Duff has written a pretty good, clear case for "single entry, multiple exit" in the form of multiple conditional return statements in a function. And Rob Pike has made a pretty clear case that this:

        for(i=0 to 100)
                array[i]=0;
is better than this:

        for(elementnumber=0 to 100)
                array[elementnumber]=0;
But that involves variables named with 1 or 2 characters.

The rest I pretty much agree with, except in very unusual cases.

Oh god... I had a partner in school that would name any variable x and then reuse it ad infinitum... what a nightmare.
I'd assumed that was intentional irony. :)