Narcissism of small code differences
weblog.raganwald.com
weblog.raganwald.com
I see it everywhere I look and I'm really getting sick about it. How about the rest of you?
Does Freud's "Narcissism of Small Differences" help explain why this happens?
Once in a while with dynamic languages you come across a "librarian" who likes to use the arcane language features. Perhaps more often, if you use Java, you will encounter code where a lot of AbstractWhatTheFracktory design pattern abuse is going on. However you will never, ever find the "ascetic" who rewrites the zipcode-padder using lambdas.
Sadly, most of the time you just see the typical egregious dailyWTF mess.
The story was not meant to be taken literally.
Nothing against unit tests, but I don't think they should serve as comments (which is more or less what you suggest).
If your tests define what your program _should_ do, then your tests can become (a) more understandable and (b) more valuable to new folks familiarizing themselves with your code.
It's a subtle but important (IMHO) distinction.
Therefore, even if we can find ways the Agnostic could have documented this requirement in the code, or if we installed a build server that would have rejected the rewrites for breaking unit tests, this does not absolve the others of responsibility for:
1. Making changes without understanding the requirements. They weren't documented as comments, fair enough. But did those fictional characters examine the entire system? Did they review which code produced this function's input and which consumed its output? Did they ask the Agnostic why his code didn't handle strings of fewer than three characters?
One day the Agnostic will be gone, and one day soem hapless programmer will have to do the detective work to figure these things out. And that's a great reason to document things... to save someone the detective work. But a lack of documentation is not an excuse to skip the detective work.
2. Nowhere in the story was there a bug report filed, nor an individual "tasked" (I hate verbifying) with a rewrite. Nor did the story describe someone updating the unit tests to include the "missing cases."
3. Many folks have identified the need for these fictional characters to communicate. Note that in the story, even after the problem is identified, all four characters carry on behaving exactly the same way. The Agnostic at least tries to talk to the others, then gives up and just codes. None of them step back and ask the kind of questions you are asking here. None of them step back and figure out that there is more at stake than what to do with two-character zip codes.
So... what I am saying is that I agree with you, and on top of my agreement I am suggesting that even if we are finding ways the fictional Agnostic could have been a better developer, we shouldn't stop right there. We shouldn't let the others off the hook.
If I read it correctly the story is supposed to illustrate the problems that can arise when developers are tempted to rewrite something just for the sake of writing it differently. This should normally get people to think about what causes said urge, but I'm guessing nobody followed that train of thought. Then in your update you brilliantly stated
"it’s about the dynamic of programmers eager to rewrite code in their own image, and the hypothesis that our [...] motivation for doing so is to emphasize the small differences between ourselves and others."
Since this is something I'm guilty of myself I would have liked to see more comments on your hypothesis and other possible reasons for this interesting phenomenon. I still don't know if I have anything intelligent to say on the topic, I'll have to give this some thought and if I get any insights I'll probably reply on my blog.
a. I won't have employees or
b. They will follow standards.
Either way, I'll never have the problems in the original article.
We'll be far too busy addressing issues to be arguing over details. I have never tolerated that from employees and I don't imagine I ever will.
However, our customers were complaining bitterly about bugs and missing features. They had a totally different idea of craftsmanship. Certainly our written standards could have been expanded but I found that the core issue was that the engineers had latched on to code quality when our customers really wanted them to latch on to software usefulness. The fault probably lay with the managers, as we couldn't figure out what was the useful thing we wanted to build. Thankfully one of the engineers invented Twitter in his spare time and we were all saved (a simplified but mostly true story).
The best approach to this I've ever found is the solicit agreement to a few simple rules and standards. Things like:
- Don't fix it unless it's broken.
- Don't delete any code. Ever. (Did I say ever.)
- Don't bypass tools we've agreed to use.
- Don't violate standards we've agreed to follow.
- Quick and dirty isn't quick. It's only dirty.
Often the violator doesn't even realize what he's done until you point it out. OP was obviously a caricature, but you still gotta stay on top of it.
I fully agree with your rule about quick and dirty. I'm currently rewriting a module that was "designed" with the "I just want to get it done" approach to software engineering.
What's the old saying? A few weeks of coding can easily save you 5 minutes of design?
We're also missing a deadline. But what is the point of meeting the deadline if we have to throw out the code afterwards and start over anyway? It is better to do it right the first time. A solid system a few days late beats a crappy system on time.
In my opinion, if the code is so complex and messy that you can't see whether individual pieces are correct, then it must be considered broken, even if it compiles and does something.
Of course. I was referring to code deleted from everything, including the version control system. By the time someone noticed, it wasn't findable even on backups. Believe it or not, in some shops it does happen.
I'm a little wary of code standards. I've found that they can be a bag full of cargo-culted banalities like "never use break statements", "never have more than one return statement", "the tertiary operator is the spawn of the Devil", "if you use a one-liner if-statement you will hang", or "duplicate all of the version control history by hand at the top of every file". I'd feel much more comfortable if I worked in a small team and we all got together and agreed on some important and useful standards rather than have them dictated by a manager who used to code back in the 90s.
And more importantly. Every standard is meant to be broken. It's just supposed to make you think about why you're breaking the standard. Cost-benefit and all that jazz.
I actually left my last startup because they hired an engineering manager who was more into test/code ratios and migrating to the latest deployment framework instead of fixing longstanding user complaints. 6 months after I left, the (easy to implement) features our users were complaining about are still not up on the site, and I see job postings looking for a new engineering manager.