Coding/Programming nightmares. Those forced on you and the ones you left for others

Do not leave the smart people alone with the toys. We will play with them in unintended fashion.

I worked with an engineer, the lead guy on a project that I came along to after it was a couple of years mature. It seems this guy knew just one kind of sort: a bubble sort. Every time he needed a set of things in order, he’d write a bubble sort inline in the code (this was long before standard libraries/templates offered good sorts built in). Once when I was trying to figure out why something he wrote was so non-performant, I realized he’d managed to write a bubble sort that called a bubble sort on every bubble. Doing an action in a set with just a couple dozen or so records would just go away and noodle for like 10 minutes every time you did anything in the app.

Someone on my floor in my dorm had a project for some Mechanical Engineering class. You had to find a set of gears for a given gear ratio (e.g., 0.8765). There were constraints for maximum number of teeth and total number of gears IIRC. You could use any programming language on any hardware.

He wrote the program in LOGO (a language often used to teach kids programming and typically involves drawing pictures with commands like RIGHT 45; PEN DOWN; FORWARD 25) on his Commodore 128. I am guessing most folks used FORTRAN on the University’s VAX (thus was circa 1987). It ran but it was not the fastest…

Brian

Going back to dev gamesmanship, if any of you haven’t seen this before it’s kind of cool.

It’s not exactly obfuscated coding, but it’s close. And arguably at least some of it has a useful purpose for deployment-constrained settings. I’ve used it a couple times over the years.

This reminds me of some code I stole from a consultant that implemented height balanced trees.

As you probably know if you’re reading this thread, binary trees are data structures that you can store data in and hopefully retrieve again fairly quickly. In the average case data can be inserted or retrieved in O(log n) time (reasonably fast) but in the worst case, like if the data are already sorted, it’s O(n). (pretty slow)

Height balanced trees avoid the worst case by making sure that the two sides of any sub tree have similar height and the tree is not just a long linear list. So, great, I stole height balanced trees and could use them store and retrieve data quickly.

Problem was all the code that used the trees was really slow. When I looked more closely, I saw that, instead of storing the height of each subtree in its node, the code calculated the height of the subtree every time it needed it. Calculating the height of a subtree is O(n) so inserts into these trees were O(n log n)–worse than a linear list.

had to fix for a cow-orker.

First we have to enumerate the entire index to check by string comparison if our search key is or isn’t a member. Then once we know it is, we go ahead and issue the query against the data store to retrieve the corresponding object.

Worked OK on mocked hashtables with a couple hundred members. Did. Not. Scale.

“Why??!!” you ask as your forehead repeatedly slams against your keyboard. Turns out the guy in question “didn’t like” how the query operation returned its KeyNotFound status and this way he “never” had those failures.

As you might expect, he also was also real bad about noticing blind to race conditions. His mind was single-threaded and therefore the rest of the world was too. No matter how many computers, processors, cores, processes, and threads were involved in the multi-layered app we worked on.

My favorite comment I ever wrote myself was in my PhD work.

The comment was something like:

/*
All of the strings coming in at this point are provably true.
Do NOT under any circumstances change any of the strings in any way that compromises the truthfulness.
Look, you’re going to think that you can split them and find some subset of true or true/false strings. They end up all being true/false and the algorithm breaks.
Do not try this. You’ve already looked at it for a month. It doesn’t work. You proved it doesn’t work, so don’t try it again.
*/

Brilliant!

Some scabs just can’t remain unpicked for long. There’s that weird nagging amorphous doubt (or potentially awesome insight) that sends you down dead-end rabbit trail after dead end rabbit trail.

I hate it when that happens.

Here’s a comment I made over a decade ago that I still remember.

// 01-20-2006 : This would probably come as a surprise to the original
// author, but the above function call (SetAllDynamicColProps) can and sometimes
// does recur, sending us back into this function via HideVisibleCtrl, of all
// things. The problematic side effect of this is that sometimes the internal
// state of this object gets replaced in the process, causing pLTBase to be left
// pointing into unallocated data space.
//
// Because this cockeyed recurring system actually does work for the most part,
// I avoided making any structural changes or rewrites to it. The main problem
// is that, at the end of this function, the invalid pLTBase pointer is used.
// Re-populating it destabilizes the algorithm somehow; however, it appears that
// restarting the process over again does not. On the second time through the
// recursion doesn’t cause a problem (though it does occur), since the internal
// objects don’t need changing again.
goto TRYAGAIN;

Sometimes evil begets evil.

I had one project where there were objects with a lot of fields like:

bool isCase1_m;
bool isCase2_m;
&c...

And every method would be structured like:

void method1() {
   if (isCase1_m) {
     ....
   } else if (isCase2_m) {
     ....
   } else if ...
   }
}

With very rarely anything in common between the branches.

I’m not normally one for super-deep object hierarchies, but clearly this is just someone who needed an object hierarchy and didn’t want or know how to make one just implementing a poor-man’s version virtual function dispatch themselves.

goto? GOTO!?
Horrors!

Which is why those two words got a 142-word comment, and why I wrote “Sometimes evil begets evil”.

In old languages without decent loop exit statements gotos sometimes were useful to avoid tying yourself in knots about when to exit the loop. One of my PhD oral questions was on this - a trick to catch anti-goto fanatics. (This was about 1976). I taught assembly language and didn’t get caught.
Totally useless in newer languages, though.

I wasn’t just exiting, though - I was rewinding. I was jumping to an earlier point in the function to give it a second shot at it with the member variable values it had collected the first time through. This is not the sort of thing I would recommend anybody ever do, but dammit, it was an ugly situation and it actually worked.