Ask HN: If your code no longer makes sense to you, do you leave it as is?

6 points by amichail ↗ HN
There was probably a good reason why you wrote it that way a long time ago.

So as long as it seems to work, wouldn't leaving it alone reduce the probability of introducing bugs?

21 comments

[ 2.9 ms ] story [ 61.6 ms ] thread
If you wrote it and no longer understand it, you wrote it and/or documented it wrong.
I'm much more comfortable rewriting code if I have good unit test coverage around it.
If my code no longer makes sense to me, and I wanted to change it, I would just take the time to understand it. I'm really confused that you would choose any other option.
Agreed, no matter how old my code is, even from a decade ago I can just use the same analysis methodology I use for any other piece of code.
If your old code doesn't make sense, you better sit down, engage the code and figure it out.

Otherwise you have to concede that you're getting dumber. Someone better than you wrote code you don't understand, and it happened to be your younger self.

If two people code up a solution to a problem and only one person can understand one of the solutions but everyone who looks at the other can understand it easily, who wrote the better solution?
The better solution is the one with fewer bugs, fewer dependencies and less resource use.

If the solutions are both correct and use the same approach, but one has managed to make it understandable, then that is better. Understandable beats obfuscated, all else being equal.

The solution that the programmers don't understand reveals a weakness in their analytic skills, though. The author could well be smarter or know more techniques, or both.

It's easier to write code than it is to read code. That's why there's so much emphasis on documenting and why someone inevitably writes functions that already exist.
We simply cannot make this generalization. It is obviously false of other creative activity involving writing; it is not harder to read a novel than to write a novel, for instance. However, it's easy for someone to effortlessly spew stream-of-consciousness drivel into their blog, which is painful to read for someone else. It is more or less so with programs.

There is one way in which reading is absolutely harder that writing. Writing (a given revision of the code, or any other text) is only done once. Once you have written that, nobody else has to write that ever again.

Reading is not like that. Nobody can read it once, so that then nobody else has to read it. Everyone who needs to read it must do it for themselves; explanations and summaries given by others who have read it before only go so far. Even one individual must repeatedly read it in order to get it, after which he or she will forget it anyway with the passage of time. The code doesn't "stay read" the way it stays written; if you come back to it in 25 years, there is nothing to write (other than a new revision, but my point is no need to write the original revision). If you come back to reread something in 25 years, you might as well have never seen it before.

That's pretty much what I do. I'll add unit tests and do maintenance, and if possible I generally aim to rip it out completely and replace with a third party library, but I won't rewrite just because I don't understand it, unless it's causing trouble.

If I need to add features to it I'll consider it though.

I would probably just sit down and figure it out, this has never happened to me but from time to time I have to think for a minute or two what something I wrote a long time ago does.

If it needs rewriting, I'll rewrite it.

You should never remove a fence that you do not know the purpose of. The code you don't understand was not created by an idiot! And fences do not grow spontaneously. That person was solving a problem, and that problem had requirements those requirements are what this code is at least a solution for.

If you don't understand the requirements, you likely don't understand the solution and potentially the problem either. In such circumstances it is best to either not intervene, or take the time to familiarize yourself with both the problem and the solution before you attempt to intervene.

Usually, the problem is that the code was created by an idiot. Me.
the way I see it is there are 3 things to consider. confidence in test coverage, tolerance of the client and whether we charge by the hour.
If I get lost in code or something seems wrong, I comment it out and re-write the logic. I might clean it up later or just leave it in.
I’d start by either stepping through the program (gdb, pdb, or a debugger of your choice) or adding more test cases - that’s often a quick way to understand what a piece of code is doing.

Either way I wouldn’t leave it as is, that’s just a recipe for ensuring it becomes even more opaque over time

I agree with dvorak_typist. Just recently read about Chesterton's Fence clearly applies here.

BUT this is a sign and a lesson for you to improve your documentation.

You should be able to sit down with any code you have written and understand it by reading the comments.

IMHO: Any code that is NOT documented sufficiently that you can puck it up later is "Throw away code!"

I start making test cases until it breaks, then I rewrite it. If it doesn't break, by the time I have likely figured out how it works and I leave some comments to make it easier for the next person to understand it. Most of the time though I just try to forget that I saw it. Once I've written a comment like "there be dragons" to warn others from threading deeper.
There's an old joke about if you write code as cleverly as you are able, then you won't be clever enough to debug and maintain it.

I sometimes code out "in long' if I feel it is necessary. That is, I deliberately add extra lines to 'show my working'. As in, perhaps:

         variable = foo( bar( baz( stuff )));
might possibly be laid out as

         bazzed = baz ( stuff );   /* comment one */
         barred = bar ( bazzed );   /*comment two */
         variable = foo ( barred );   /*comment three */
to show how and why a particular result is generated, if I feel the original code is too abstruse to see quickly why it is so.

Yes, there is a (usually) negligible time cost in the running of the program that might even be fixed by an optimising compiler. But I will save a lot more time than that for myself and any other programmer in the future when maintenance time comes around.

Interesting. I'm quite the opposite in that I'll try pretty hard to avoid unnecessary allocations. In the case of your example I'd do something like:

  variable = foo(bar(baz(stuff)));
  // baz stuff
  // then bar the result
  // which we finally foo. 
I primarily write python which can't optimize out the allocations so that might influence this.
If it provides value and doesn't need to be adapted then I'd probably leave it as is. If there are tests that I have faith in and the code is really poor I might try to touch it up if there's nothing better to do.