(This is a very programmer-centric article. To my loyal subscribers who were hoping for the usual filth: I can only apologise.)
I’ve been a “professional” (ha-ha) programmer in the games industry for just over fifteen years. “Professional” in this context means “gets paid for it” rather than “high-quality software engineering”.
The games industry is quite a brutal subset of the software industry – the hours can be long, resources limited, tasks are unpredictable, and you’re often expected to perform miracles. There is little room for failure. On the plus side: the work is rarely dull.
I seem to have spent a large amount of my career in a firefighting role – assigned to large, existing projects (often with long-standing issues and deep-ingrained problems) and asked “how soon can you fix this?”. When I’m in a cynical frame of mind, I sometimes employ metaphors involving dead-horses or cash cows that haven’t quite been milked inside-out.
Following some recent geeks-in-the-pub conversations on this subject, and a recent job interview where I dragged out this particular soapbox and preached from it for quite some time – it seemed a therapeutic idea to get down my opinions into order … and possibly offer it as some sort of advice.
And it is only that: opinions and advice. It works for me, but your mileage may vary. If anyone finds themselves in a similar situation and needs to know that they’re not alone, then I hope this helps.
A typical situation
First day at your new job, and you’ve been assigned to a project that’s been in development for a few years and has things that need fixing. Your new boss has just dumped a load of work on you (he’s probably a manager rather than a programmer) and he wants to know when he can see some results.
When you see a project for the first time, it is easy to be overwhelmed at the sheer enormity of it. The source-code to a modern computer game is massive. To give you some idea: my last project weighed-in at around 2,500 files, adding up to about 280 megabytes of plain-text data (and that’s just the main game, ignoring all the support tools and scripts). As a basis for comparison: the NIV Bible is about 2.5 megabytes of text.
That code was written by potentially dozens of people before you. Many of them have now left the company, so you can’t ask them about any of their work. And you have no idea how good they were at their job. And now it feels like it’s all on you!
It is difficult to remain unfazed by this. It is easy to get defensive. But how you react to the problem you are presented is your choice.
It is unlikely that you’ll be working completely alone. There will be other programmers working alongside you, and if they’ve been in that position for any length of time they will know what state the codebase is in. They’ll be sympathetic to your plight, because they’re in it with you.
Your demonstrated attitude will be seen by your colleagues.
You will be more respected if you’re positive and constructive. If you spend all your time moaning about “whichever idiot wrote this piece of shit” you will not be heralded as a genius – you’ll be dismissed as a whinger. They probably know the code is cranky; that’s why they employed you.
If you find a piece of code that was written by an idiot … double-check you’ve read it properly.
Occasionally I hear stories about people who bluffed their way into programming jobs, and made a terrible mess before they were forcibly ejected (or promoted away from anything sharp). But this is a rare occurrence. Programming skill is a difficult thing to fake, and easy to test for in interviews. In the vast majority of cases programmers tend to be pretty good. So, pause to consider this: the guy who worked on that code before you was probably very intelligent.
Therefore, it is possible that you’re reading it wrong right now. Consider carefully: the code you’re about to write may be the thing that makes your successor shout “which idiot wrote this?”
If you find a piece of code which really IS unutterably awful … consider that there was probably a really good reason for it to be there.
There may well have been very good reasons why that programmer wrote what he wrote. You’re not seeing the whole picture. And we’re not just talking about the codebase; we’re talking about office politics, management decisions, time constraints, and so on.
Perhaps another piece of code (which has since been removed anyway) relied on it. Perhaps it was left over from a partially-completed refactor. Perhaps it was written at 2am and that programmer was tired and not thinking clearly. It might have been done immediately before a deadline and he figured he’d fix it properly “next week”.
Best to think happy thoughts! Replace the code with something better. Or, at the very least: comment it, so the guy that comes after you won’t have to suffer the confusion you’re suffering now.
If you write something which you know is dreadful, comment it as such.
My colleagues must be very sick of my rants about code comments, but this is my blog, so there.
Let’s say you look at a piece of code which seems … dreadful. Based on my previous points, you’re now worried: is it a bad piece of code that I should replace? Or is it doing something that I don’t comprehend? Does a seemingly unrelated piece of code depend on it, and I won’t realise that until I remove it and everything else falls to pieces?
Dilemmas like that are why bad code gets left in. A programmer sees it, is 99% convinced it should go, but won’t remove it “just in case”.
Refactoring code is one of those things that young and innocent programmers do with wild abandon. But when you’ve been stung by the fallout of that – other code breaking, intermittent bugs and memory leaks that take an age to track down – you become more cautious and cynical. Better to leave it in (you reason) and waste a tiny amount of space, rather than suffer the potential consequences. Man-hours are more expensive than computer-hours.
But if you were to see a piece of code which seems poor, and has a comment above it saying “This is crap. Sorry, I know it is. Please remove and refactor at earliest convenience.” wouldn’t you feel better for reading that? Wouldn’t that help to reassure you that you were correct in your assessment?
All programmers have written bad code at one time or another. We’ve all written stuff that is shameful, but it fixed the immediate problem and allowed us to go home to bed. If you’ve done it: you’re amongst brothers, there’s no shame in admitting it. (Can someone give Dave a manly hug, please? I think he needs it.) As long as you comment why it is poor and why you had to do it then at least the coder that comes after you will be confident he can remove it.
Comments don’t cost anything. They won’t make your code slower. They’re helpful to your colleagues and to you.
Comment all your work. Leave the bathroom cleaner than you found it. Take personal pride in what you make.
“If you can’t explain it simply, you don’t understand it well enough” is a quote attributed to Albert Einstein. In the context of computer programming, I translate that to “if your code is too complicated to understand, you’ve probably made a shitty job of the algorithm”. Which is not nearly as punchy, and I doubt will appear on any of those ‘inspirational quotes’ images that get distributed around Facebook.
If you have taken a very complicated problem, and solved it with code which is so simple that people can just skim over it and barely realise it is there … then you have done a good job, and should be very proud.
All too often I see programmers over-engineer problems, slap a dozen templatised-classes in where a simple array would have sufficed, and write zero comments … and they seem proud of it. Actually: they should be ashamed.
The difficulty is knowing whether the code you’re about to write will also be required in problems that haven’t yet been defined. So: do you write code that fixes the immediate problem, or do you try to predict what you might be asked to add next week?
This sort of judgement is what comes with seniority in programming: you have a pretty good idea of what you’ll need to write, because you’ve been stung by it before. But if you really have no idea which way to go: my advice is to keep it simple, then refactor later if you need to. When code is too complicated it’s very hard to make it simpler. But simple code is going to be easier to understand if someone needs to rewrite it later.
As a responsible and professional employee, you should be adding value to the codebase which lasts even after you’ve moved on. If someone inherits your code after you’ve left, takes one look at it and decides “this is too complicated to understand, I might as well rewrite it myself” then what good have you done? Where was the value in employing you?
Knowing all the programming techniques is great … but knowing when NOT to use them is even better.
I see quite a lot of code written by programmers who clearly keep up-to-date on the latest techniques and language extensions, but perhaps have not learnt restraint. Just because you know about C++11, lambda functions, and template metaprogramming … doesn’t mean you have to use them all the time. Programming skill is not about demonstrating you can use those techniques; it’s about knowing when to use them.
You should NOT be coding to make yourself indespensible.
To write code that is so incomprehensible that your employer has to keep employing you is a shitty tactic, and ultimately futile. If your boss wants rid of you, he’s already decided which junior programmer will inherit your responsibilities. Which means that your convoluted code won’t bother your boss in the slightest – but it’ll give the junior a nervous breakdown. You didn’t “stick it to The Man”. You stuck it to a brother.
If your employer seems to make a decision which seems to you – as a logical programmer – against all sense … don’t moan about it.
This often happens if a programmer doesn’t get the time they need to do it “right” (as he sees it). To us, it seems very short-sighted that we’re not allowed to rewrite <insert name of random project or subsystem here>, and it’ll just bite us on the ass later.
Remember: we are just programmers – but it’s their company. Though we may find it frustrating, they have more to think about that just code elegance. They have a business to run, and a Bigger Picture to consider.
All we can do is present our case; our “ideal” solution. But expect it to be shot down – very few software businesses will agree to waste a year or two employing programmers to completely rewrite their product to be more elegant under-the-hood, but with little or no tangible benefit to the paying customer.
Besides, the programmer dream of being allowed time to write code which is “perfect” is a money pit. When was the last time you were ever completely happy with a piece of code? Exactly. And you probably never will be, either.
If you do approach your bean-counter boss with a proposal to rewrite a large amount of code, you need to think like them and present it in a way they can understand. “I want to re-write this code because it’s a mess and ugly and scary and looks at me in a funny way” won’t cut it. But “If I rewrite this code now, then adding the new features you want in next year’s project will be much simpler” might work – they might be able to move some budget around.
Your manager may not be able to think like a programmer – but perhaps you could try to think like a manager?
When your ideal solution is shot-down, have alternatives. What else could you do that’s more constructive than just adding another hack to all the other hacks? What can you do for your employer that will make the code better?
Your attitude is important. For YOUR health and YOUR state of mind.
If you take nothing else from this article, I hope you’ll remember this: your success as a programmer is not just about your skill with ones and zeros. It’s equally about your mental attitude.
Viktor Frankl said:
“Everything can be taken from a man, but one thing: the last of human freedoms – to choose one’s attitude in any given set of circumstances, to choose one’s own way.”
To paraphrase: outside influences may hinder your work, but your attitude when working is always entirely within your control.
I initially dismissed this as trite … until I read about Viktor Frankl himself. Viktor was an Austrian Jew who had everything taken from him during the second world war. And I mean everything: he lost his home, his possessions, and almost all of his family died in Auschwitz and Kaufering. So when he says that a positive mental attitude is always possible, and vital to your health … I think we should listen. You may be feeling poorly-treated at work, but seriously: your office isn’t Auschwitz.
Please don’t think I’m preaching that you should always toe the company line, and remain deliberately-blinkered of whatever suspicious practices are going on around you. I’m not trying to suggest that you should accept any crap that gets dumped on you and burn yourself out “for the good of the company”. I’m saying that keeping a positive mental attitude is essential for your well-being.
When faced with a poor piece of code and high expectations from your boss, you decide your attitude to the problem. The task won’t magically shrink if you moan about it. It’s still there in front of you. But psychologically, the more you build it up as a monster, the harder it will be to solve. Always remember that it is not a dragon to be faught – it’s a problem to be solved. You’re being paid to make something work that is currently broken, and actually … that’s a pretty awesome job.