The seven sins of programmers

The seven sins of programmers

Programmers. The system administrators worship their bit twiddling capabilities. The users exchange vast quantities of beer for new features and tools. And the project managers sell their souls when they make the magic work. But inside the average programmer’s psyche are several demons that need exorcising.


This is all too common in programmers. Instead of asking whether a particular function exists, or for the best way to retrieve data from the system, a proud programmer is likely to write their own. Especially when faced with a large, or unfamiliar, code base. By re-inventing the wheel there are now two very similar routines. Not only does this increase the code size, it doubles the amount of maintenance required, creates another opportunity for bugs, and adds inconsistency. Later, when another programmer sees these two functions, they will have to choose between them. Which one will depend on their mood (are they also too proud to seek help?), who’s on holiday or who’s outside smoking, at the time! This can equally be applied to duplicate constants, member variables or structures.

Code reviews... must focus on the code, not the coder

Code reviews with a senior team member can help quell a developer’s pride, and guide the other developers in the appropriate direction. This is basic employee training, and one that is simple to implement. Reviews also force the developer to reason each decision made, and justify the creation of new utility routines, perhaps explaining to the lead why existing standard code was not used. To be constructive the review must focus on the code, not the coder, and support free flowing ideas, regardless of the relative seniority of the reviewers. Remember that if the developer is too proud they’ll be closed to ideas, or won’t suggest improvements.


Programmers should improve themselves by learning from others, not blindly emulating them. All coding methodologies (be they syntactical or design-based) come with caveats. A programmer might inline a function with the pre-processor because he’s seen it done elsewhere, unaware of potential side effects, as in this classic example.

#define SQUARE(x)   x*x

Similar evils occur when programmers move between languages. An experienced developer will typically have a specific style that he tries to crowbar into every other language. Perl written like C. Java written like Ruby. We’ve all seen the examples. Naturally, you should use the best tool for the job, and work to the strengths of that language. By trying to fit idioms from one language into another highlights the fact you understand neither. It’s a development fact of life that some languages are better suited to some tasks, so adapt to it, and close those envious eyes that look at the language you’d rather use. Remember the oft-quoted saying, “When all you have is a hammer, everything looks like a nail”.


Not an evening at the all-you-can-eat buffet, but the problem of writing too much code. Every hour spent coding will require an extra hour of testing, and possibly two more of maintenance. And guess who gets lumbered with the maintenance?

Worse still, this does not scale. A two-minute feature (or one line bug fix) may also take an hour to test. Whatever your gluttonous reasons are—attempts to impress, an under-staffed team, late night camaraderie, or personal pride—curb them. Spending the whole morning trying to unravel last nights two-minute feature is like the buffet—you get stuffed afterwards!


Programmers crave pleasure; they love to “scratch their own itches”. If unchecked, some developers will write fantastic, innovative, original... and completely unnecessary, code. It could be a new graphics shader, a faster search algorithm or an entire processing engine! If you’re working on anything other than a pet project, you will probably have a schedule that must be adhered to, and a set of pre-determined priorities. These affect the whole project, and not just the wanton lust of an individual developer. Unless you are called Spock, the needs of the many, outweigh the needs of the few... or the one.

Make sure any code written is actually needed. Will it get used? Or will it distract the users who, in turn, add a new plug-in system, just to make use of the code? One very common example of this is premature optimization. Without profiling the code it is impossible to tell exactly where the bottlenecks will occur. Granted, most developers can look at a function and give several reasons why it is slower than it could be, but very few can tell you want percentage of the total running time that function will occupy. Unless it’s known to be on the critical path, then it’s probably not worth optimizing at this time.

The desire to write new code can also exclude the possibility of introducing middleware as a viable solution. The cliché chant is then of “Not Invented Here”. Programmer X once said,

“I’m not using middleware since I don’t understand it; it’ll be just as quick to write it myself. How can I be expected to maintain something I don’t understand?”

He was erroneous for many reasons. Firstly, the initial period of evaluation would give him experience with the code base, and should be a pre-requisite when introducing any new code to a project. Secondly, he’s only considered the development time in terms of coding, when in actuality much of it is taken up with testing—something any sensible middleware product would have in abundance—and as we’ve already seen, writing code doesn’t scale to the subsequent testing and maintenance phases. And finally, there are other trade-offs between write and buy, such as access to other developer forums, paid consultancy, and third party contracts which determine whether the purchase of middleware is a good idea for your specific project.

Curbing programmer lust in this way allows more time spent on the important tasks. This would include writing original, novel, parts of the software and learning the middleware solution itself. After all, it is usually quicker to read, than to write.


Do not code out of anger. Do not ignore good ideas, regardless from where they come. If a more junior programmer has a solution to the problem in hand—discuss it. If it works—use it! The engine programmer should not be allowed to implement his own solution just because “He’s the engine programmer”.

Anger leads to hate. Hate leads to suffering. To bad code does that lead

Do not code out of spite. Lead programmers: love your coders. Code reviews, for example, should raise the ability of the whole team, and not be used for leads to show off, introduce new jargon, demonstrate obfuscated syntax or exhibit other prima donna characteristics.

Do not code out of fury. Programmers: love your leads. They distribute work because it needs doing. Don’t work on somebody else’s tasks because you’re more suited, or believe it should have been yours. If you want to move into other areas of programming, talk to your lead. Develop prototypes at home. Employing enthusiasm in this manner will win more brownie points than ignoring the task list and schedule.


Don’t procrastinate! If a particular piece of code is uninteresting or difficult (like an obscure crash bug), more interesting tasks should be available to compensate. Look forward to those tasks, but don’t daydream about them. If you stop every five minutes for a coffee and chat (or more likely, a whinge) then the task will take much longer, and it will become a self-fulfilling prophecy. Instead, begin with a cup of coffee, a bag of sweets, and your favorite MP3s. Then lose yourself and knuckle down to the task in hand. It won’t be as bad as you think as even dull work makes time pass quickly if you become engrossed in it.

Also, make sure all the tasks are clear, consistent and given from one manager. Opposing requests from different managers will make one of them unhappy, and starting such a doomed task is no fun for anybody.


There are a couple of places where developers suffer greed. We have already touched on one, and this is a programmer’s innate desire to do too much. The proverbial “biting off more than you can chew” scenario leads to an exponential increase in testing, and a swell of code paths to verify. It can also lead to a lower quality of code since the problem domain may not be well understood by the developer assigned, and the increased workload limits their opportunity to learn.

The final greedy point is directed more towards management, as everyone should feel valued—financially and metaphorically. This is especially true during crunch-time, when even the most junior programmer can work out that their hourly pay packet could be improved by working on the cold meat counter at Tesco! Paying for late night food goes without saying (I hope!), but an occasional pub evening also helps. This gets everyone out the office, and shows that management aren’t greedy with an employee’s time, either. Many ambitious people, regardless of salary, always want more. So even the lead programmer will start questioning their role and think “I’m worth more than this” when they feel unappreciated. How many times do you hear “I’m so overpaid”, compared to “I’m so underpaid”?

Leads should check for warning signs, like “funny” comments in the code—“I’ll do this properly when I get a fscking pay rise!!!”. Management should be wary of stopping or limiting low-cost company perks (such as free soda) since the loss in productivity and willingness to do overtime is undoubtedly greater than the few dollars spent. Follow Dilbert. Less money for staff does not mean more for management.

Naturally, the lead programmer should help prevent such sinful practices. But as responsible professionals, we should all try and curb the devil inside first. Of course, not everyone is Beelzebub incarnate, so score yourself honestly out of ten for each category, and ask a colleague to do the same for you. Then compare. I score 4, 2, 6, 1, 1, 2 and 3 on the categories above, but pride prevents me from letting you in on which scores are for which categories...



Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

good one

Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

...should instead read "try to curb". Also, some of the material was shoehorned a bit too much in order to fit the biblical sins. Otherwise, a fine article.

Edward Macnaghten's picture

A line like

y = SQUARE(x++);

would evaluate to

y = x++ * x++;

which is probably not what is required

Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

y = SQUARE(x++);

Actually, SQUARE(1+1) would become 1+1*1+1 (=3). Then, the smart comes and defines:

#define SQUARE(x) ((x)*(x))

Just to later find out that s/he was not that smart, because it does not solve SQUARE(1+1).

Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

The square function may already be defined with other options as well.

Square function for multiplication may be a quick hack, but if you already have a function #define SQUARE() for a different area of the program (ex. - dimension of a box rather than a number multiplied by itself), you can run into a lot of pesky unrelated errors.

Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

I think the author has committed the sin of arrogance.
To charge other programmers with sin simply because they
must develop useable software within a timeframe that does
not allow them to study the complete scope of a language or
application framework.

One caveat: I am a "born again" coder of functions which may "duplicate" other existing software. I learned that I can spend more time learning how to use existing software than it takes to code a duplicate module. Plus, I don't waste time debugging someone else's code because they gave up trying to find a fix a thorny problem but didn't make any note for others who may trip over it.

My biggest sin? I use flat files for database applications which have less than 100,000 records. They are always compettive with SQL databases in performance and can be developed in one tenth of the time.

All that said, I enjoyed reading this article and encourage others to consider these ideas with the thought that they should be applied in moderation.

I look forward to reading more of your articles Steven.

wurakeem's picture
Submitted by wurakeem on

I agree with you and the author. My personal approach: borrow if you think you need to borrow and write when you can.
Notice my wording: most programmers don't like borrowing so they do it when they really need to. Otherwise write if the environment permits. I am in the financial field so development with component reuse is standard under constant deadlines.

borrow vs. roll your own really boils down to 4 main factors:
1. time alloted to complete project
if you know your schedule then you can very easily determine whether a fancy approach or a pedal-to-the-metal approach would fulfill the requirements.

2. management opinion about the approach
if your higher-uppers are all about buying components or encouraging or expecting your code to use existing infrastructure, it would be dumb on your part not to follow that. If they're okay with you building on other dependencies and give you the time to do it, why would you argue ?

3. great ability to estimate time it would take.
This is something that all developers should try to hone as much as possible. This is a crucial skill that will save your tail in the line of fire and will make you shine when it comes time to deliver. If your estimate says that reading docs and learning the API would take longer than writing your own implementation then so be it. Don't make a decision based on your opinion about reuse, but based on the time cost.

4. know when to stop
This is another big pet peeve with developers. Let's say you wrote an app from scratch and it is 70% complete. Suddenly you notice that there's a much better (even standardized) way of doing it, using a 3rd party library. You start reading the docs, you play with the API but you're stuck because of some errors you get with the API. Whether it is your fault or the library's fault, if your time is running out you must revert to the old approach and finish it. Maybe when management approves this new approach you can call it version 2 and tell them it will take a little longer due to this issue you encountered. Just don't get bogged down trying to do it the "right way" first time around.

Anonymous visitor's picture
Submitted by Anonymous visitor (not verified) on

I saw something similar to this in the Anti-patterns book (ISBN 0-471-19713-0) which has been around a while. Who attribute the idea to a book called the Online Deskbook.

Their seven sins are:

Haste: they talk about compromising because of time.
Apathy: they talk about not wanting to solve known problems.
Narrow-mindedness: they talk about refusing to practice solutions that are otherwise known to be effective.
Sloth: Poor decisions based on the easiest answers.
Avarice: (Greed) They indicate there are a number of types, but discuss architectural avarice which means the system is overcomplicated with excessive detail.
Ignorance: The intellectual sloth, not seeking to understand.
Pride: Not-invented here.

I think that the front-matter of this book is definitely worth a read. It also some interesting reasons as to why software projects fail. Which have been reproduced here.

On a separate note, whoever runs this site, if I could leave my name without registering I would. Why should people want to register on every blog they write on--- Drupal is quite capable of accepting names and personal details for one-off posts. Why not turn it on?

Infernoz's picture
Submitted by Infernoz (not verified) on

Please everyone read the "Peopleware" book, it was like an epiphany when I saw that some people genuinely understood what can go wrong in creative environments and how they can be improved. A sub-optimal or unstable environment can be a far worse barrier to development than developer behaviour and actually cause developers to misbehave.

Author information

Steven Goodwin's picture



He is also known as the angry man of open source.
