When Understanding means Rewriting

The author wrote “it’s that very few developers are smart enough to understand code without rewriting it”. I’m sorry, but if you don’t understand the code, how are you supposed to rewrite it correctly? As Joel pointed out, old code had a lot of work-arounds (and tricks) added up over time, and unless you understand that code and its dependency with other code, you should just leave it alone (or add more work-around to fix a bug). Having said that, I’m not at all against rewritting code: if you understand a bad code 100% and sure that you can write better code to replace it, go ahead and do it.

With regards to Feynman being ga-ga: At least based on his own biographical essays, it is clear throughout his life that he understood theories better when he worked out the details himself, so it was not a newly formed view at the time of his death. However, Feynman was a genius and so was well able to do the work to walk through a theory in detail. This does not mean that everyone is compelled to do the same, or that this works best for everyone.

There are more than just the two choices: read the source code, or rewrite to understand the problem domain. Almost all code nowadays builds upon other code, sometimes closed source, and people still manage to build lots of useful software on top of it.

It seems this is oversimplified – i.e., it’s true of that part of my job in which I’m interacting with the code, but it is not true of the bulk of my job, which is non-coding requests, and/or groking just what is being said in a defect report.

I suppose it’s kinda sad how true that pie chart is, but at the end of the day if you don’t spend as much time trying to understand the code all you end up doing is wasting an extra hour on recompiling bad code that was never written properly in the first place.

Why would you think that reading source code in isolation is any way to understand how a program works in the first place? Of course you have to know what an application does before you can work on it. Of course you have to understand how to use it. But you still have to read the code to modify it. It’s not an either-or choice, you have to do both.

And the idea of re-writing code because you don’t understand it strikes me as self-indulgent and amateur. Re-write to make it better, sure. But don’t re-write because you don’t understand.

The real problem is that very few developers are able to write good OO code in the first place.

Legacy Code: Code which noone has the stomache to maintain.

Most refactorings i do on the job are turning code vomit into a slightly more OO design so i am then ABLE to make a fix/add a feature.

I agree with the original post. A few other comments…

  1. Rewrite code only after you fully understand what it is that you are rewriting.
  2. Don’t rewrite code because you don’t understand it. It’s tempting, but you might miss critical concepts that are imbedded in the implemetation thats non-intiutive to you. In other words, the other guy might have a messy implementation, but it might be for a complex problem.

I have been coding for many years, and this is something that i learned early on:

The poorest coder implements a simple task in a complicated way. That one i rewrite every time.
The average coder implements a complicated task in a complicated way. That one i might refactor if possible.
The superior coder implements a complicated task in a simple way. That one i tip my hat and try to learn.

Coders typically want to rewrite code implemented in a complicated way.

The best you can hope for is a simple task that you can implement in a simple way and get home for 5.

If you have the privelege of having the person who originally wrote the code have a stab at asking that person to walk you through the semantics of it. Just a couple days ago I was able to save a week’s worth of code/re-writting because the developer who wrote the original piece was able to walk me through what he did and w/in an hour I was ready to modify his stuff…I know that most developers would rather die rather than look for help or look “weak” but if you’re choosing to take the path of least resistance ask if you think you can cut on waisted effort.

Jarocho

Nice post,rewrite is easier.

This post struck a chord for me… I’ve been working at this fun little web dev shop for just over a year, a nice no-bull workplace. What absolutely baffles me on a daily basis is that the other two coders are old school, in the sense that they write strictly procedural code with practically no separation between logic and presentation. The scary thing is they’re all very good at it, which seems so fundamentally wrong to me :slight_smile:

I’m coming from the opposite camp. I like OO, I like reusable modules, I really like logic separation so I can throw new clothes on an old app and sell it to someone else. Needless to say, every time I crack open an old site, I start tensing up as I stare down the business end of a few dozen ad-hoc SQL queries, optimistic data validation routines and long HTML+code paragraphs that lack any structure whatsoever.

After a year, I’ve become a bit more comfortable cutting through the mess, but that’s largely because I blank out my mind and focus solely on fixing the bug or changing the text, without paying any attention to context beyond what’s directly needed. I’m like a horse with blinders, avoiding distraction at all costs. If I don’t, sooner or later I will cave in to the primal urge to rewrite the whole codebase from scratch, and my coworkers will hate me for forcing my neat structures and encapsulated building blocks down their throats.

Here is my personal experience.

I have not yet re-written an application that did not greatly improve the application functionality, extensibility, reduce amount of code and do it in less time than expected.

Not once.

One of the problems with patch working ANY existing application is that unless the change is minor you end up having to fully understand the application as well as all the existing code anyway and the process of understanding the existing code is basically to read and “write it” in your mind. This takes at best the exact same amount of time as it would to re-write, usually more.

Now, I do want to point out it really depends on how many issues there are and where the problems are located and it does take some instinct to figure out when you are about to re-write all the code in your head anyway in order to understand it.

Let me begin by saying I’ve been reading this site for a while but I never felt the need to comment, until now. I agree with the main point of this article but I also feel that in order for you to understand the article a programmer may need to observe the program in action, use the program themselves, read the code, and then step through the code using a debugger. When I am given a large project that requires some revision they are the steps I take; it cuts down the time from the begging to the end of the coding process.

I have a brother that is a computer science professor. Some of his programming exercises allow a student to go out and find code that closely matches what they need, understand it, and then make changes to suit their needs. I feel this is the best way to teach a programming course because it isn’t too often that a programmer will start from scratch (a blank page). It not only teaches the students to be resourceful but it teaches them good techniques (through trial and error) on how to read and understand code that was written by others.

I forgot to add, another reason for the huge chuck of the chart being understanding code is that a lot of the time programmers will write code, let it sit for a while, then come back to it. In order for that programmer to complete the code they first must reread it to ensure they understand what they did and what direction they were going.

There is one minor flaw in the concept of just rewrite everyting. When you rewrite it, you will introduce new bugs. Then you will have to fix them, at which point it is old code again, and you will need to rewrite it again, making new, different errors.

Isolating the area where the error is, and what the real need and intention of that piece of code, then rewriting only that one small piece (small enough to reasonably be assured that it can be done bug free) may be a better solution. However, it does not get you out of the business of reading and understanding old code.

Conclusion: Rewriting is easier and faster, but the final product is no better than the original. Only by fully understanding what was done, and why it is right and wrong, can we make contunual incremental improvements.

Rewrites are usually a guise for I want to add programming language X to my resume, so lets rewrite this component in language X, although in some cases technology has evolved which dictates a major change.

Programmers should spend more time on design of the application and components, then there wouldn’t be the need to rewrite it. If the design is good, then maintaining and addng improvements should be rather easy.

I spend most of my time rummaging through code to figure out how it works so I can either fix it or add enhancements without breaking antyhing. Sometimes an innocent small change can wreak havoc on the system.

When designing something from scratch, keep in mind that your system will need to be modified and updated. If you make allowances for this, the design can be carried forward, thus eliminating the need for rewrite. Writing code is easy part. Good application designs are hard to come by.

Jeff,

This is a great article. I know from a personal point I have been known to rewrite portions of code that is hard to follow and understand just to try and get an understanding of what the original programmer was thinking. Your comment about how hard it is to explain what an application does makes me think of some the work I am currently doing. Supporting an application

I think the best way to understand what an application is doing is kind of like what you mentioned with taking a car out for a spin with your own wheels. Actually running the application and seeing how it behaves in different situations really helps shed some light for me (as well as reading the massive amounts of source code and highlighting different sections). Thank you very much for your time and I hope you have a good day.

Brandon

‘Haacked’ is right that having good clear tests are a useful element in understanding code - they document what the code is intended to do.

They’re certainly not enough on their own though… tests may tell you what a single class does, but they don 't tell you how the components fit together.

Good blog. Here are a few thoughts:

A lot of functioning code uses major hacks (Linux Kernel for example). I’m assuming that most people advocating rewriting code are Java programmers because I doubt they would even attempt to rewrite some of the assembler code in the kernel, or rewrite some binary “blob” code for wireless device drivers. And that’s about as ugly as code gets.

If the bridge works for many years and doesn’t fall, nobody cares if it looks ugly or very few can understand how it stays up (but suspension bridges do look pretty nice).

I agree that software sucks because nowhere near enough time is spent designing and re-designing. I’ve seen developers cringe when their code was examined by qualified people. I’ve seen end users marvel at the stupidity of a user interface. I’ve seen buggy apps that will NEVER WORK. That’s when you redesign, review (as many times as is necessary), and THEN rewrite.

Finally, I personally have been part of development teams making software that served NO ACTUAL PURPOSE. The ideas which spawned the creation of the software were fundamentally flawed in ways that a teenager could determine:

“we want to make the Internet more like TV.”
“But we have TV and it sucks.”

“We want to sell huge items online.”
“Shipping the huge items is more expensive than the item itself.”

Don’t rock the boat…

I’ll throw in my two cents.

When writing software, often one is writing it in the midst of a “fog of war”: there are unknowns.

Later on, perhaps these unknowns become clear.

Rewriting must be done to serve: (i) a business purpose, or (ii) a new purpose.

If no purpose is being served: otherwise what’s the point?

If you find yourself fixing bugs constantly - probably just rewrite the troublesome areas.

1 Like