Programmers often have difficulty going back to older code bases because they don’t reflect the latest, greatest idioms. It can be hard to work with constructs that you know could be better, written with less code, stripped of even more duplication, beautified. But it’s important to realize that all code will eventually feel like this.
Even if you take that project from three years ago and scrub it clean as can be today, it’s still going to drift from the best practices of two years from now. That’s normal, it’s natural. You continue to get better, to learn, and the technology you’re using is hopefully progressing as well. Yet it can still seem like a hard hill to climb to get back in to yesterday.
Suck It Up
Here’s something I don’t say often: Suck It Up. If you work on more than a few projects, they can’t all smell like today’s fresh linens. It doesn’t mean you’re a bad programmer. It simply means that you’re prioritizing.
Yes, yes, you should clean up around you when you dive in to those older applications, but beware the lure of a full Spring cleaning. You’ll get pulled in and before you know it you’ve broken half the application and won’t know how to get back out with your ego or tests intact. Add your feature, fix your bug, and leave everything you touch in better condition than you found it, but that’s it. Move on from there.
This is not a license to be a slob. Whenever you’re starting something new, you should always try your best to infuse it with the top of your game. That way you can hopefully drown the feelings of disappointment with at least a dash of nostalgia: “Hey, when I worked on this I did the very best I could. How great to see the progress of my skills and sensibilities since then. Good job, me!”
Doug
on 12 Mar 08DHH
You advise sounds to be exactly why Merb was created.
Merb is a rewrite of Rails that’s thread safe, cleaner and faster than Rails.
Noah Everett
on 12 Mar 08I find the more passionate/excited I am about a project the cleaner/more thought I put into how I structure my code.
Also I looked at some code I wrote over 2 years ago and its actually neater than what i write now. I probably shouldn’t admit that.
clifyt
on 12 Mar 08I learned this just recently…having some time on my hands, I decided to go back and clean up a few sites I use to run (err…should still be running).
Good ol’ ASP Classic…still have a webserver just to run this old legacy code. Not going to touch the code…just get things converted to XHTML and validate to some standards…and finally get rid of the inline styles (hey! some of this is over 10 years old). Ok…just a little. It is amazing that after using much better languages, you realize how much cleaner you could have programmed the chunky language and that it really wasn’t a bad environment in the first place…
Doug
on 12 Mar 08Also, to follow up my original comment…
Is the 19 year old Josh Peek, the partime 37signal’er mentioned yesterday, the person “cleaning up” the Ruby code written by programming Gods at 37signals?
JF
on 12 Mar 08Doug, it’s interesting how 19 year old Josh Peek exhibits a level of maturity far above yours.
Any more off-topic posts and they’ll be deleted. This post has nothing to do with Rails or Josh.
Matt Radel
on 12 Mar 08Holy crap it’s the Troll Cap! I’d almost forgotten about it!
Seriously though, this is true for designers that code as well. I’m constantly improving how I mark things up in html & css and it’s very obvious when I work on a project that’s even a year old. It’s nice to see when & how you’ve made progress, but you’re also cursing yourself at the same time.
markus
on 12 Mar 08I dont think this is entirely true. The thing is that over time one develops certain habits and patterns which reflect onto one’s thinking ways too.
Compare ruby to python idiomatic, once you thinks that
array.include? ‘dog’
is naturally, it is hard to leave that route of thinking.
Another important aspect is where and how to store data. One could use XML but why – its less readable than yaml. And XML is slower than a database too.
You slowly will start to use certain practices and this will also impact on the code. For example, I use yaml for most of my config stuff now, and if i need other files, I generate them via ruby.
I dont think I will ever go BACK to the Unix-nature of various formats with their different rules. I simply dont want to.
Ruby is much more elegant than all the *nix world can think of (with one exception – i think pipes are the best unix concept ever invented)
DHH
on 12 Mar 08I don’t think we disagree, Markus. I’m talking about existing code bases for your own applications. When you learn new way of doing things, you’ll certainly apply them to all new instances going forward.
But that doesn’t mean that every time you learn something new that you have to go back and revert all those old implementations or usages on the spot. You’d be busy doing nothing else very quickly.
Lars Fischer
on 12 Mar 08I totally agree with David.
Luke Noel-Storr
on 12 Mar 08Perfect timing!
I’m about to start work on version 4 of an application I originally wrote 8 years ago, and I’m not looking forward to facing the terrible looking code in there (though its on version 4, it has changed little over the years). This has given me a more positive outlook on things.
It always nice to think that an application I wrote 8 years ago, the first commercial code I wrote on after uni, is still being used 8 years down the line – no matter how bad the code may look to me now.
I’m still not looking forward to coding in Java again after a year of Ruby though!
matt
on 12 Mar 08Great post, glad to see I’m not the only one who gets that “not so fresh” feeling when I review old code.
some guy
on 12 Mar 08this has been known for quite a while.
it’s just that in the past, you’d probably be using C or some other language that was basically a portable high-level assembly language, so it came in the form of code rot, where the code wasn’t simply just ugly, it didn’t work anymore because of changes in machine architecture.
Edan
on 12 Mar 08Counterexamples include: several Lisps and Smalltalks.
mkb
on 12 Mar 08I don’t see how Code Rot goes away with any new language. Any software with a dependency on a changing entity (compilers, JVMs, ruby version are all exampels) is subject to it.
sandofsky
on 12 Mar 08The advice goes for any refactoring. I jumped onto an app after its initial rush-job implementation, and I was agast. I went overzealous with refactoring and broke things, and it became harder to argue for future refactoring.
The best way to improve existing code is to budget extra time for general maintenance when adding functionality.
Kerry Buckley
on 12 Mar 08I initially read that as ”...with your ego or testes intact”. Not sure which is truer.
Avi
on 12 Mar 08Yeah, ignoring the lure of the spring cleaning is important. You can’t always be perfect, and when choosing between perfect and done, I’m always lean toward the later.
Radoslav Stankov
on 12 Mar 08Oddly, on Monday I was thinking about the same things when I was forced to use and old code ( 2-3 years old, untouched, ugly … ). I spend most of the day just cleaning, styling, optimizing, but not chaining a single thing in the api. The result was fantastic: 50% less code lines, 45% small file sizes, over 60% speed improvement.
p.s. The strange thing I noticed there was that the lines where very short and some expressions and others were split into 2-3-4 lines, witch make the code very unreadable at some points. What I remember than was that when I wrote the original code my screen size was just 800px, now I’m with 1280px screen.
Tom
on 12 Mar 08I really enjoyed this post.
It’s very tough to fight the urge to refactor old code when you go in to simply maintain it. When faced with this, I try to assume that the code sits as it does because other components of the system depend on it. Whether or not it’s good code is kinda moot at this point (being years later)
I’d hate the factor a function and end up playing Jenga with the project.
Tammer Saleh
on 13 Mar 08What I find hardest is balancing the “cleaning up around you” with leaving the app in a consistent state.
With the exception of basic bug fixes, I’ve found that it’s better to document sweeping changes as todo items, as I come across them. That allows me to later budget enough time to make those changes application-wide (maintaining consistency), and helps keep me focused on the task at hand, and out of the rabbit hole.
Ariel Meilij
on 13 Mar 08Yes, but old code brings back old memories… 1987, yes, Qbasic in a CP/M workstation… No windows, we used curses library back then. No GUI. Thank God we had input screens… We used batch programming! The data entry guys would kill me if my input screens had anything on them. Those guys would type numbers fast as light… The code was elegant… We had no OO then, no classes… Functions were used when needed. Anyone would understand your code, the whole accounting application could fit inside a 5 1/4 floppy and there was still place for files…
Sniff, sniff. Those were the golden days…
Joe
on 13 Mar 08I work in the aerospace industry, writing in Fortran77 for most of the day.
Old code bases force simplicity but whats interesting is that hacks become so obvious, you start to wonder who had good programmig practices back in the 80s.
Writing code that’ll last is truly a huge challenge, but whats probably more amazing is just how long code will last – often alot longer than the developer thinks it will.
Spike
on 13 Mar 08This entry sure hits close to home. I’m having to work on code that I wrote 5 or more years ago, before I had a clue. Not to say that I have a clue now, but I have a more developed sense of what NOT to do. I have scars to remind me.
Avoiding the urge to clean house or to delete a line that you don’t think should be there is something I’ve learned to approach very cautiously. I learned this mostly by observing what happens when other programmers on my team do this without talking to me about why something is the way it is.
Code and developing can be like a big ball of mud. Layers upon layers that build up, harden, and get buried by more layers. How fun it is to start fresh with your own little squishy ball of soft and malleable clay.
Devan
on 13 Mar 08This post rings so true for me – Thanks for sharing your thoughts David.
I have been using the same (windows based) programming language for nearly 20 years now, and have also kept every scrap of source for every project I have written in that time.
Looking back, I can see how my style has evolved, gotten a lot more cleaner and efficient over that time (Yes, even improved DRY principles).
Every time I look at the older code base, there is a sore temptation to go back to it and make improvements based on what I know now – but I know that way madness lies.
Rather, I use that opportunity to reflect on how much my style has improved. Same thing when I listen to recording of me playing my guitar from years ago…
Matt
on 13 Mar 08David’s points certainly ring true. Over the last couple of nights I have been doing some work to clean up a site I built a year or so ago – mainly cosmetic, XHTML tweaks, better cross-browser compliance etc and before I know it I am wanting to port the site over from wordpress to chyrp, rewrite my custom modules in a more OO way etc etc. This morning before I even saw this post I started thinking that perhaps I needed to stick to the scope of this smaller project. If kept tweaking everything else nothing would ever be put live, the client would get annoyed that I was constantly changing it etc etc.
I think as programmers we are inclined to always look at new ways of solving problems so when see our old code and think “Hey I can do this better” we naturally want to prove to ourselves that we can. We also want all our work to be our best work, when we see old code we want to update it to reflect our current knowledge and methodologies.
We like challenges, we like re-inventing the wheel sometimes – Its the nature of the beast but do also have to move past our old projects, use them as as learning experience and apply what we learn to the next project.
Jon Vaughan
on 13 Mar 08It’s not always that you would have done it differently – often when you look back on something you remember only a high level set of functionality, so when you see the code you think gosh why is this all here? But then once you get into the code you realise that there is a lot more to it.
JH
on 13 Mar 08@Markus
Ruby is much more elegant than all the *nix world can think of (with one exception – i think pipes are the best unix concept ever invented)
What?
Complexity != A lack of elegance
The fact that I can reliably log into ANY *nix box in the world and poke around, edit files, etc. IS elegance.
OMG, the fanbois around here…
rick
on 13 Mar 08I’m reminded of this ALA article.
“Good programmers rewrite, great programmers refactor.”
Laurel
on 13 Mar 08Generic programming blog post: “It is bad to do x too little, but it is also bad to do x too much”
To throw another analogy, it’s true that your house will eventually be a mess—once you move in it’ll never be perfectly clean. But there is a huge range of messiness (and like code, beyond the basic health and hygiene issues, it has a lot to do with the personal tolerance level of the people who live there). And there are some people that should keep their places nicer, and some people that should chill out a bit.
I think there is a lot to be said for leaving code better than you found it, rather than just working around the mess. The art and skill is determining how much to clean up (and when to stop).
Before I had a dishwasher I would end up with all of my mugs dirty and in the sink. When I wanted a cup of tea, it worked out better to just wash them all instead of just one. And maybe put away the ones on the drying rack.
But if I stopped to remodel the kitchen I would never get my tea…
Kerry
on 13 Mar 08I agree with Laurel that the art and skill is determining how much to clean up and when to stop. I also think the ability to recognise when the overall structure is reaching the unmaintainable point is critical.
Last year I did some work bug-fixing some changes to a large set of code that had been continually added to over a period of 12 years. Changes to the functionality had been repeatedly shoe-horned into the existing structure to the point where it was almost impossible to recognise the structure. Part of this was because choices were made in the original design that assumed certain elements of functionality wouldn’t change, and implied in that was that such change should have lead to stepping back and rethinking the design. Instead the structure had been stretched to incorporate these changes – repeatedly. A big step last year was to step back and reevaluate the code and the functionality – particularly which functionality was changing alot. The result was a complete re-write – which we based on a set of principles for how the code should be structured. Could we have rewritten it earlier? Yes, but recognising the point at which we should is easy in hindsight. Going forward the principles we established for this particular codebase should help in recognising the next such point – provided we keep enforcing those principles ;-)
Seth
on 14 Mar 08DHH – spot on.
It’s too bad more people don’t realize this. I want to reach through the computer and slap people who whine that Substruct isn’t compatible every time a new Rails version comes out.
I’ve since gone with shipping the proper Rails version with the distribution. (and probably the Gems it needs as well…)
Tom G.
on 14 Mar 08This is always important to remember before criticizing somebody else’s program.
Hindsight is 20/20 and assuming that people had all the advantages of todays technology and know-how years ago is foolish.
Peter Cooper
on 14 Mar 08Well that makes me feel a bit better about the Rails 0.8.x level code I still have in production on one site. Yes, it’s still using @params[‘x’], render_text and all! Unfortunately freezing to that version wasn’t viable, so I had to do the bare minimum (and a few hacks..) to get it to run on Rails 1.x where it is now safely frozen ;-)
Paula
on 14 Mar 08David’s got a point. I’ve been dealing with this issue for a long time, when you are a bit of a perfectionist (close to obsessive) this could become a real problem. Even if you decide to improve the code at you own expense, usually your client won’t understand the point of it, improvements might not be visible for them at first sight (my clients are not the kind that are measuring page loading, even less code beauty).
Lately I came up with a simple solution: when expanding an old project, I review the code and set-up a fixed number of hours to work only on improvements that will clearly enhance the site’s performance. If I feel tempted on doing more I got a short cut to my bank account balance that has a truly discouragement effect ;-)
Monique
on 15 Mar 08SUCH a good post. Thanks! It’s nice to know I’m not alone and I appreciate the reminder on prioritizing.
Phil Crosby
on 15 Mar 08This was very useful to me—I always rewrite everything, and I have trouble prioritizing my time.
However, don’t dismiss rewriting either. If you plan on doing 20 hours of changes to the project over the next 6 months, leave it as it is. But if you’re going to be hacking it often, the investment in a better framework will pay off—if not in dollars, than in less of a nagging frustration that comes from working with something suboptimal.
Stephen
on 17 Mar 08Everything in moderation, including moderation itself. ;-)
JackHill
on 18 Mar 08It was really very gud
This discussion is closed.