Sunday, 26 April 2009

The Most Profound Advice You Will Ever Receive

Strangely enough, I received the most profound piece of advice I have ever heard in a pub out in the wilds of Wales, while on a stag do. We'd spent the day quad biking, shooting, and engaged in other equally testosterone-fuelled activities. We'd had our curries, and were sinking a few beers before the stripper-that-the-groom-didn't-know-about-but-fully-expected was due to arrive.

I got talking to one of the guys, and the talk turned to babies. My wife was pregnant, and I expressed some concerns about my ability to deal with the immense responsibility of caring for and raising a whole new human being.

"Don't worry about it." came the booze-fuelled reply from the father of three. "You already know everything you need to know. If they're hungry, feed them. If they're cold, warm them up. If they're too hot, cool them down. You'll be fine."

At that point an approving roar announced the arrival of a comely lass clad in a nurse's uniform, and we all lost interest in the conversation.

But the guy was absolutely right - common sense will take you a very long way as a new parent. And that it why I have no hesitation in awarding this particular piece of advice the most profound I have ever received.


Last year I was chatting to a new father-to-be, and he asked me for advice on dealing with a new baby, as he was freaking out about the responsibility etc etc as mentioned above. I furrowed my brow, drew myself up to my full height, pretended to be thinking thoughts of the utmost profundity, and passed on verbatim the advice given to me.

He didn't believe me, of course, but I hope that in the fullness of time he'll appreciate my astuteness.

This got me thinking about what advice I would give a newbie engineer, in the hypothetical situation where such a person were to ask me for advice on programming. I say 'hypothetical' because (a) nobody's ever asked me for advice, and (b) as a newbie, I was so self-confident and arrogant that I rarely asked for advice. I fully expect the new generation(s) of engineers to be exactly the same. Indeed, I found that the people who tried to give me advice were almost without exception fine instances of a combination of arrogance and incompetence. My favourite piece of expert advice is still that function prototypes are a waste of time, so don't bother with them. Absolutely priceless, you can't make this sort of thing up.

Instead I just wrote a whole bunch of dreadful code, slowly and painfully worked out what worked and what didn't, and over the years developed an approach that now serves me well.

So, if asked for advice, here is what I would say. These will form the basis of a series of blog articles over the next few weeks/months, depending on how often I find the time to sit down with my netbook and a few glasses of wine.

1. Use version control.
2. Use unit testing.
3. Do it right the third time.
4. A quick wrong decision is often better than a slow right decision.
5. When in doubt, use brute force.
6. Fail fast and hard.
7. Learn a scripting language.
8. Use static analysis.

Sunday, 12 April 2009

Unconscious Programming

If you've ever spent any time trying to learn a new skill you may have noticed that you go through a well-defined sequence of steps. Learning theorists tell us that this sequence is independent of the skill, i.e., it applies whether you're learning to play the piano, ski, paint, or whatever.

Having been through this loop a few times myself, the explanation I like best is laid out in Gestalt learning theory (aka the four stages of competence). This tells us that we go through the following steps when learning a skill (caveat: I was told this by a bloke in a pub, and haven't bothered to research it in any depth whatsoever, but I have found it to be true):

1. Unconscious incompetence. You're rubbish at your new skill, but are happily ignorant of the fact.
2. Conscious incompetence. Having banged away at it for a while, you start to appreciate the full depth and width of your ignorance and inability. I vividly remember listening to some Jimi Hendrix after having been going to guitar lessons for a year or so, and being completely blown away by how freakin' GOOD the guy was. Believe me, if you've never tried to play the guitar, you have no idea.
3. Conscious competence. You can do it, but you need to concentrate on it. It's a bit of an effort, but it's all starting to come together.
4. Unconscious competence. Everything's effortless. Doing everything properly is just part of your DNA, you've got to the point where doing it any way other than the simplest, most direct way is just an alien concept that makes no sense. I love to watch people at this level, whether playing instruments, turning wood, building a wall, or whatever, I have complete respect for anyone who's really good at what they do. Especially stuff I've had a go at, and so have some idea of how complicated what they're doing is.

Jeff Atwood recently blogged about the eight levels of programmers, with the Knuths et al of this world sat at the top of his pyramid. And rightly so. But I think there's a lot of mileage in the Gestalt model. I can see my arc of progress through it in a few areas I've dabbled in. I guess the main problem with it is that you can't really judge your own position in it. After all, how do you know when you push on through from unconscious incompetence to conscious incompetence? How do you know that you're fully appreciating how bad you are at [insert area of interest]? These are judgement calls that can only be made months or years after the fact.

I also have a sneaking feeling that the whole cycle is exactly that, a cycle, where you get to some level of mastery, and then start to realise that, actually, there's a whole new series of levels out there that you were previously unaware of. And at that point, you've just gone back through to conscious incompetence again.

I suspect that programming is a particularly fertile area for this sort of progression. There's a seemingly never-ending progression of bright and shiny new things to play with - say hello design patterns, extreme programming, generic programming, OOP, UML, ....

I know that I'm easily distracted by such baubles. After mainlining on the Gang of Four I spent at least a year in which my code was full of Singletons, Observers, Factorys, etc. None of which improved the code in any meaningful way, and in most cases actively made it harder to maintain for those following in my footsteps (mental note: must send a box of chocs to those poor sods). Which isn't to say that such things don't have a place, just that they should be in my code on merit rather than on a desire to play with some fancy notion I've read about.

Over the last few years my code has become noticeably leaner and simpler, and I think this is a good thing. I've also been working with resource-constrained microcontrollers for the last few years, rather than desktops which to all intents and purposes are infinitely fast and have infinite memory (I know, I know, I'm exaggerating for comic effect, but after you've spent a couple of days trying to save 100 bytes so that you can fit a program in a 4K chip, you get a totally different perspective on things).

I like to think that I passed through one level of unconscious competence (that I now think of as smug complacency) and am now nearing the end of another cycle. Which leaves me wondering where I'll go from here. What will I think of my current self in two years?