“[E]verybody wants to build and nobody wants to do maintenance.” – Kurt Vonnegut, Hocus Pocus
This post is part of my sporadic Notes to a Young Software Engineer series.
A common story in software engineering goes as follows:
X, a well regarded senior engineer with a bevy of experiences, has recently joined the team, and worked their way through the code base. Their takeaway: the code is riddled with poor design choices and atrocious code. It needs to be largely refactored.
Sometimes, this makes sense. More often than not, the code is actually solid. Far from perfect, but effective given the shifting requirements and increasing user load during its conception.
The true “issue” is that the code isn’t written in the way the new engineer is used to. Rewriting lets them make the code look the way they prefer. It is also more fun to design a new system, than it is to spend days learning about an existing system and augmenting it around the edges.
I’ll make an only partially hyperbolic exhortation: software engineers should write less code.1
The downside of code
Writing code has several critical flaws.
First, code requires effort to maintain. I liken writing a line of code to taking out a loan: your return has to justify the debt you’re taking on.2
Second, in the engineering-led startups I mentor, writing code — rather than talking to users or focusing on product — is the most common mistake. This shows up in symptoms like premature scaling and using too much new technology.
Third, favoring one’s own code means you’ll ignore external tools (or someone else’s code) that might have solved the problem. This bias is what underlies not invented here, when all external solutions are looked upon suspiciously.
The drive to code
Given the issues, why is there such a huge bias to writing code?
First, it’s fun. Most software engineers can recall the moment when they did their first write-run loop. This same sense of accomplishment underlies so much of the programming we do in the years since. Take away a programmer’s ability to code, and many software engineers would quit en masse.
Second, challenging problems — say a hard algorithm — are more interesting to work on. If you had a choice to work on a hard problem that gave you intellectual fulfillment versus outsourcing it, many would do the former even if the task at hand is better served by the latter. At a friend’s company, his team was so excited about building a new database — with its data structures and new query language — that they ignored external tools that would do the job better.
My friend Andrew3 likens a great engineering team to the American army: You assemble a great engineering force with the hope of rarely using it. An exceptional team should save you from over-engineering. The danger is that it makes over engineering ever more likely. The hammer sees a nail everywhere and engineers often look for outlets to exercise their skills.
Third, to become a great engineer, you have to write lots of code, ingraining this drive in contexts where it makes less sense. My favorite college lecturer likened early programmers to cars, with his role to “put mileage” on us. The more he demanded we code, the more mileage he was putting under our belts. Writing code, thus, let us learn and grow. But this impulse leads to over engineering outside the classroom.
In a job or a critical personal project, solving the problem in the best possible way should outweigh our own personal desires for what we want.
In these contexts, it makes sense to ask a few questions:
- What is the cost of writing this code? This question requires you to think about the medium and long term. Who will manage the code? What potential changes will need to be made?
- What other solutions are available? External tools often outweigh home grown solutions, even if they require work to customize to your use case. The monetary cost of many external tools often pales in comparison to the cost of an engineer’s salary.
- What biases do I have?: When you enjoy working on a certain problems, it means you’ll go after them even when it may not make much sense for the task at hand.
You can read more of my Notes to a Young Software Engineer series. All opinions expressed are solely my own. feedback or ideas for other posts? drop a note to softwareeng at this domain
- Given my views, I expect this to be one of the more controversial posts I write. ↩
- In software, we talk about technical debt, without realizing that it refers to far more than hastily written code under unclear requirements. Every line of code is debt. ↩
- A cofounder of PagerDuty and fellow Y Combinator alum ↩