What's in a name?

Ovid on 2006-06-18T18:17:54

If you're familiar with chess, you might know the old saying "a player with a bad plan will beat a player with no plan". As a general rule, once you commit to a strategy in chess, you should keep up that strategy unless diverting from it gets you a very clear gain which your opponent cannot overcome. A player who plays for the moment with no eye towards the overall game will rarely succeed in the long-run. Conversely, a player who only looks at the long-run will often overlook tactical opportunities and can be outplayed by a player who knows this weakness. The great majority of players, though, play for the moment. They might have an idea of some long-term goal, but they're constantly looking for short-term advantage. In chess, those players are generally known as "losers" because, well, that's what they do.

In programming, we see something similar. We take a bad system, we start refactoring, but in the interest of "getting it done now", we only get it halfway done. This is then repeated many, many times despite the intention of gradually migrating to the "better way". Then others come along and start to work on this system and they're seeing a hodgepodge of things like &some_func and &some_func_new. Some code uses the "old style" and some code uses the "new style" but it's not always clear when it's appropriate to use either.

To be fair, a company doesn't often have the resources to simply rewrite everything. Budgetary, temporal and resource constraints all conspire to keep a "half-baked" system half-baked. However, without disciplined management and programmers, this is a very tough problem to overcome.

Since this problem is one we see constantly -- knowledge that code needs improvement and many partial efforts of dealing with this -- I think it needs a name. Once something is labeled, it's easier to talk about and deal with. Does this common situation have a name? It would strike me as odd if it doesn't, but then, perhaps it's so terribly common that it's taken for granted rather than explicitly dealt with.


And along with partial refactoring...

Alias on 2006-06-18T20:09:57

I see tons of similar decisions being made for new code as well.

Decisions which are clearly made with little thought towards the future.

Trouble is I don't see an obvious name for the overarching term other to invoke Back to the Future's "You're not thinking 4th dimensionally!!!".

That people can be suckered into trying to beating the Halting Problem, or a design decision that is clearly subject to a Tragedy of the Commons doesn't seem to me to be a general problem, they just don't see far enough ahead.

Perhaps something along the lines of "Instant Gratification" ?

(but that doesn't sound so hot...)

Re:And along with partial refactoring...

Alias on 2006-06-18T20:12:10

Premature Gratification? :)

My thoughts on the matter.

Shlomi Fish on 2006-06-19T20:23:15

Hi Ovid!

I just returned from work when I saw your message and I can understand it and relate to it. There may be one of the so-called "anti-patterns" about this, but since there are quite a few of them, I'm not sure if it will be easy to find. I'm not much of a pattern/anti-pattern freak myself (as I like to think of good solutions to problems when they are needed, and not waste precious memory remembering tons of patterns), but there are people who are more into this kind of thing. I can try asking someone I know (even IRL) who is a pattern-freak and see if he can recall anything.

While this is obviously a bad pattern, I think that refactoring is generally touted to be done in small steps where none of the steps break the behaviour of the program. Martin Fowler's "Refactoring" book contains some large-scale refactorings which aren't like that, but that's usually a rare case.

I think the main problem here is not in coding, but in management. If the management does not allocate enough time for programmers to finish refactoring, then it's a problem with the management. I'm pretty sure there's a "We-shouldn't-do-any-refactoring" or "We don't have time for refactoring" anti-pattern. Usually such management will get the project to crash and burn.

I personally believe that as long as the code works and is mostly bug-free, it can almost always be salvated (i.e: refactored and then extended). There were some successful rewrites, mainly in the open-source world, but I was never involved in that particular stage of one to know if they were completely justified.

One pattern I've been doing to some extent, which is different than that is something I call "lazy refactoring" or "just-in-time" refactoring. (for not knowing the correct terminology). What I do is refactor the program just enough to accomodate for a change while leaving other (none-critical) issues in place. I've successfully used this to develop Freecell Solver, which I wrote from scratch in C, and then heavily extended, enhanced and optimised in future releases. While sometimes I did a lot of refactoring, I often did just enough refactoring or generalisation to later implement a certain enhancement.

At present, the code still has some issues, but it's still in a shape that can accomodate later changes. I've received some negative criticism about it from people who read it and tried to understand it claiming it was badly written. To my critique, I agree that it's unreadable and sometimes possibly over-optimised (possibly even over-micro-optimised), but it is still in good shape.

BTW, today we discussed the pro's and cons of the proliferation of programming languages on Freenode's #web channel. One item we touched upon is that there's a lot of "legacy" code out there, which may be too costy to rewrite. So for example there's a lot of COBOL code, which is still maintained, because people are afraid to rewrite it in something better. (albeit IMO rewriting COBOL code in Perl would be much easier than rewriting Python (for example) or even C code in Perl, because you can do much more in one statement of Perl than in one statement of COBOL). But still it's probably easier to maintain the code in COBOL at least for the short term.

On the other hand, there's a lot of code in Perl and a lot of code in Python, and no-one wants to rewrite it from the "legacy" language to the "better" one, because it is easier to maintain it and extend it as is. As languages evolve and more powerful and more succint languages come up (I.e: C→Awk→Perl→Ruby→Perl 6), you still have the inertia not to re-implement all the code in the new language that's only slightly better. And eventually we get a COBOL-vs.-Perl 5 situation which seems incredibly ridicolous.

One of the issues we discussed was whether this fragmentation between languages that are peers (i.e: offer much the same power and roughly the same succintness, but differ greatly, like Perl, Python, Ruby, Tcl and PHP) is a good thing and whether there is any hope of preventing it. The reason why it's not good is because it makes it harder to interoperate between codes written in different languages, and also encourages different implementations.

I diverted a little bit, but I hope it's OK. Cheers, and thanks for sharing this thought with us.

Re:My thoughts on the matter.

Shlomi Fish on 2006-06-25T20:15:09

Well, I talked with my "patterns" guy. He said that one may find what you're describing in the "Big Ball of Mud" article that describes how a software project goes on to having a lot of bad code, possibly in terminal state. (Note that I have yet to read it)

As for my "lazy refactoring" or "just-in-time refactoring" - he called that "continuous refactoring", or at least thought it was a good name for it, and said refactoring should be done at small, atomic steps. You can consult Joel on Software's Rub-a-dub-dub article for documenting a one-time, lengthy and top-to-bottom refactoring, which may also be sometimes necessary.

I've done both kinds of refactorings in the past, and I hope everyone has.

Re:My thoughts on the matter.

Ovid on 2006-06-25T20:52:13

You've nailed it. Originally I didn't think about that because I had the incorrect impression that a big ball of mud primarily referred to a reasonable system which decayed with age. From reading the first bit, I see that the BBOM also refers to what I described. I think I need to reread that article again. Thanks, Shlomi!

Re:My thoughts on the matter.

Shlomi Fish on 2006-07-05T21:01:23

You're welcome. :-). I'll also try to remember to thank my expert on this as well for you.