Note – I wrote this entry about a week ago, but since my current (terrible) webhost enjoys seizing up every time I’m editing a WordPress post, I think I got distracted by sites with actual working webservers and forgot to publish. Here it is now; new webhost in a couple months.
Since writing about Code Anthem in my last post, I’ve been catching up on a lot of posts that I’ve missed (almost all of them outstandingly good), and I’ve found myself sticking on this issue of a “good programmer” and what being able to write good code means. When I read, I agree on the “bad” programmer, management, etc. counts – but I don’t think that understanding those problems automatically makes one a quality coder, and I still wonder about where I legitimately lie on the spectrum.
See, the funny thing is that in the year that I’ve been doing team lead level work, I’ve actually been writing significantly less code than when I occupied a more junior position. I’m entrenched in a lot of “legacy” – not just code, but systems, processes, etc, and it’s actually been a great fit for developing my skills and confidence, especially with the full support of our boss to rip out all legacy and start making improvements. Unfortunately, the system-level improvements need to be ironed out before the code can be, and so goes my focus. I’ve also being doing a good amount of front-end development on top of all this legacy cleanup, but still very little backend work.
Anyhow, this week my frontend work required that I write a simple CGI script from scratch. A really easy coding task, but when I was only about 10 lines in, my good friend Paralysis spoke up: “This can’t be the best way to do this.” Which, for a short moment, stopped me completely in my tracks.
Here’s how this ties back to my internal discussions while reading Code Anthem: descriptively, I should be a good coder; I’m interested in implementing best practices and I generally loathe the “Let’s just get it working” tactic. I have had experience with the coders that Amber mentions – the ones that crank something out quickly sans documentation and leave the pain of maintenance and making sense of everything to the poor suckers that come after them. I’ve been in environments where the “get it working, fast” attitude is rewarded and it’s driven me crazy. But I feel like what I have to offer as a contrast – a strong and inflexible orientation towards quality – can be equally problematic in the most extreme of circumstances.
Without a doubt, the phenomenon of Paralysis has a lot to do with confidence (or lack thereof: fear of criticism). My own gauge of quality works in antagonistic concert with my fear of coming under the scrutiny of others’ standards. Confidence isn’t the only contributor though – a lot of this has to do with simply being realistic and self-aware – knowing that one’s knowledge probably isn’t deep or wide enough to come up with the best solution for any particular programming problem in a finite period of time. Another contributor to Paralysis is empathy: being so acquainted with the pain of maintaining bad code, I cringe at the thought of contributing something that might add to the long-problem in any way, even if it adequately resolves a short-term problem.
Paralysis ruled my first two years in industry. I could tell that my superiors (at least in my first job) didn’t think I was a bad programmer, but they also didn’t understand why I couldn’t get anything done. To my credit, I had a pathetically small amount of mentoring and training for a job I wasn’t qualified for on paper at the time (note: hiring college grads in CS because they are smart – even if they immediately lack the practical parts of the skillset – is admirable, but only if you plan on taking the time to train and mentor those grads once they’ve been hired on – otherwise they’ll flounder for a lot longer than is necessary). But the other major contributor to my lack of productivity was my pathetic dearth of confidence combined with a knowledge that what I was doing wasn’t going to be “the best”.
In the last two years I’ve been able to crawl out of the Paralysis hole a bit. The key is jumping in and writing something and getting it to work – and then refactoring and fixing it up immediately, if you aren’t already doing it as you go. Then clean up and amend the documentation (which I always write excessive amounts of as part of my code, but not in the most organized ways.) This is completely different from the coders who get their first solution working and then move on to the next problem, with a horde of maintenance issues just waiting in the wings. But taking that plunge into “just start writing!” can still be so difficult! In the day I spent on this script, I felt like I spent a couple hours standing on the ledge, looking down at the problem, convinced that whatever I was going to write was going to suck. Then I took the plunge, and big surprise, the fixes came to me as I was writing. As a result, the code I had at the end of the day wasn’t perfect, but it was a lot better and more tightly written than what I had imagined it would be at the start of the day.
I have a coworker who deals with his own version of this, and being an third party to his own paralysis struggle has been really insightful. It’s often really obvious to me when he’s sweating the small stuff, and I can apply this back to the times where I’ve been doing it myself. Learning to distinguish between the problems that do deserve my perfectionist’s hand and those where I’d be better off just applying a band-aid has been really beneficial, even if applying the band-aid is never optimal. At some point, a less-than-ideal solution is preferrable to spending infinite time scheming over the perfect solution and, as a result, never producing anything.
That balance is still really hard to find, though. I think learning to manage the Paralysis beast is going to be one of the struggles of my working life, but it’s also an area where I’ve made definite progress. In my current workplace it bites me for two reasons: 1) I work for a Perl shop and think in a far more verbose way than Perl is usually intended; as a result, I know almost everything I write can probably be expressed more tersely and (arguably) elegantly than initially comes to mind; and 2) Our process hasn’t evolved enough to support code reviews (which I love), so it’s harder to drop “I know this can be expressed more tersely” when I know that my code may not be viewed by anybody else for awhile. The pressure I put on myself to get it right on the first try is a lot higher.
To a degree, though, working with a lot of legacy code has been really good for coping with Paralysis. Whatever I replace with my own stuff, however imperfect, is still a vast improvement on what was there before, and this has allowed me to spend less time worrying and more time producing. But I still find myself a bit stuck whenever I’m writing something completely new (like I did this week), or I’m making fixes on a large enough level that I have to sit back and make some serious design decisions before moving forward.
In general, I think the humility, self-awareness, and perfectionism that guide Paralysis are qualities that manifest themselves in some degree (perhaps using less loaded descriptive terms) in the mythical “good programmer”. But the mythical “good programmer” is able to utilize the best of these qualities while keeping the negative aspects in check, and is able to move forward on a problem after the proper amount of consideration and at the proper time. That’s something I’m still working on, but it’s heartening to see that I’m doing a lot better than I was at this point a few years ago.