Nothing to be proud of
I had a disturbing realisation the other day when I was asked to put together a code sample for a job application – I can’t think of a single piece of code I’ve written that I’m actually proud of. In fact, even ‘proud of’ is probably setting the bar a bit high – I can’t really think of many things I’ve written that I wouldn’t be ashamed of showing to a potential employer.
Now that, in itself, doesn’t actually worry me too much. In the context of applying for a job, I could talk at length about what’s wrong with how I’ve coded things and how I’d do it differently were I to start again – that kind of stuff actually makes for quite a good interview. I suspect that a large part of the reason I have so little code to be proud of at this stage in my professional development is simply that most of the things I’m programming I’m doing for the very first time – the first compiler you write, for instance, is bound to be a hopeless mess, because it’s often only in the coding of it that you figure out what on earth you’re doing. What’s more, as I learn the right way to code these things, my tolerance for ugly code diminishes – I often find myself flinching at little idioms I used to use with such abandon. It’s even been said that the very thing that distinguishes amateur coders from professionals is realising that everything you write sucks!
So the existence of shameful code doesn’t cause me to despair. Of more interest to me, and what this article is all about, is this: given my past experiences, why am I always so confident that my next piece of code will be different? What is it that means I’m always so blind to the probability that what I’m working on right now will prove to be equally ropey once I reach the end of it? It seems to me that it’s in the nature of computer programming that everything you ever write makes you learn something new. The result is that you’re constantly raising your standards and never completely happy with your previous coding efforts. Yet my heart seems to be several steps behind my head in realising this.
Refactoring your technical debt
In most programming projects, this constant growth means that you’re always left with something of a technical debt: pieces of code that could do with some attention to make them easier to understand, easier to test, easier to modify, and so on. It’s that piece of code in your most recent project that you know wasn’t quite “clean†enough for your liking, but which you didn’t have the time or energy to sort out at the time. You can usually get away with ignoring your technical debt in the short term – generally it doesn’t actually mean anything is broken, functionally speaking – but the cruft tends to accumulate and if you don’t give those areas of the code the attention they need, eventually it can lead to real problems.
People who are blindly optimistic about their abilities, like I seem to be, are likely to be content with the classic Waterfall Model of software development. This is the approach that assumes everything will go exactly according to plan – that everything will be perfectly designed in all its fullness, then perfectly implemented with no architectural flaws whatsoever, before being released to perfectly happy customers who are receiving everything they hoped for. Thankfully, most people these days seem to be realising that pretending this works doesn’t actually get you anywhere. Instead they’re embracing agile methodologies like Extreme Programming which are built upon an explicit acceptance of our human weaknesses – imperfectly knowledge, imperfect requirements, imperfect decisions – an assumption that happens to synthesise very happily with a Christian worldview that is only too aware of our sinful nature. One of their key tenets is the idea of Constant Refactoring. If you haven’t come across the term before, “Refactoring†describes the process of modifying the internal structure of your code and tidying up interfaces and so on, but without changing the observable behaviour. It’s about paying off your technical debt, little by little, until you have a code base you can be proud of. Agile methodologies embrace refactoring, because they know you’ll need to do it – they know you won’t be satisfied with the way you coded it the first time around, or even the second or the third. Of course, refactoring has to go hand in hand with repentance – a commitment to turn from your evil ways as a cowboy coder and start putting into practice all that you’re learning. Refactoring without repentance is a pointless exercise, since the chances are you’re just replacing one technical debt with another.
Refactoring the Christian life
But if it’s in the nature of computer programming that constant growth means you’re never completely happy with your previous coding efforts, how much more is this true of the Christian life? How often do you find yourself cruising along, thinking everything’s fine spiritually, only to look back on the last few weeks and notice some massive area of ungodliness that you’d overlooked: maybe some action of yours that really hurt someone without you even realising it, or maybe some persistent behaviour that you later realise has been a dreadful witness to your non-Christian friends. It’s part and parcel of the Christian life, for as Jim Packer says in “A Passion For Holiness“, growing up as a Christian is really all about growing down – that as we grow we “end up seeing ourselves as less – less nice, less able, less wise, less good, less strong, less steady, less committed, less of a piece – than ever we thought we were. We stop kidding ourselves that we are persons of great importance to the world and to God. We settle for being insignificant and dispensableâ€.
As God sanctifies us and conforms us bit by bit to the image of his son, we find our consciences flinching at things that previously never bothered us. Our tolerance for sin in our lives should always be less than it used to be – so long as it continues to be greater than God’s. As in programming, repentance is a way of life for the Christian, not something that you do once when you first decide to follow Jesus. The difference, however, lies in how we must deal with our past failings. For whereas bad programming leaves us with a technical debt that I can solve myself with a bit of refactoring, bad living leads to a spiritual debt that nothing short of death can pay for. Writing bad code has no legal ramifications
– although I’ve previously argued that there is a Christian imperative to write the best code we can out of love for our co-workers and our employers, I’ve not broken any laws by writing bad code. I don’t face a jail sentence or a hefty fine. But bad living, on the other hand, is a legal matter. Rejecting God’s rightful rule over my life and choosing my own path is tantamount to treason, and carries a penalty that I have no hope of paying myself. It takes the death of Jesus in my place as a substitute to set me free. For a proud programmer like me, becoming a Christian is an act of the utmost humility, as you admit to God that you are unable to offer anything towards your salvation, and that only the death of his son Jesus can pay off your debt. As Romans 6:23 puts it, “the wages of sin of death, but the free gift of God is
eternal life in Christ Jesus our Lordâ€.
Thank God for the ultimate software architect, the Lord Jesus, who refactors my ugly past, pays off my spiritual debt and cleans up the rope in my life so that I can get on with daily repentance as I seek to follow in his footsteps.