9 Psychological Components of Good Code
Welcome new readers! Forwarded this email? Subscribe here. Enjoy this email? Forward it to a friend.
9 Psychological Components of Good Code
Hello futurists,
When did you write your best bit of code? How did it feel? Do you think you can do it again?
Personally, I know that my code quality has a huge variance. Seemingly similar days and codebases can produce large differences in how good my work is. What explains this?
Some of the answer is obviously skill. Programmers (generally) get better over time. But that's not the whole picture. Your skill goes up in a smooth line. The output is far more jagged than that.
I came to realise that much of the difference was not anything tangible. Instead, it was psychological. How I felt about the work I was doing was the biggest factor in how good it was.
After some further thinking, I identified 9 factors that help me and the teams I'm part of write better code.
1. Ownership
There are two ways that ownership can manifest itself in a codebase. I call them property-based ownership and clarity-based ownership.
Property-based ownership is, in the words of Nassim Nicholas Taleb, 'Skin in the Game'. It occurs when developers are motivated intrinsically by their own goals. When code actualises the developer's own values, not someone else's, and makes money in proportion to the value they create, a sense of ownership is achieved. The code, in short, feels like a piece of their property.
Time is a strong factor here. If you do not expect yourself to be on a project for very long, you are less likely to write good code; you will not be around to bear the consequences in the future. Know you'll be dealing with the code forever, on the other hand, and it will receive true care and attention.
Teams obtain clarity-based ownership when it is always known whose responsibility it is to write particular features and fix particular bugs.
I used to live in a ten-person house. As you can imagine, we were not very good at tidying things up. When a messy living room is everyone's responsibility, it is no one's. Passing the buck on the hoovering becomes all too easy.
The same problem occurs in engineering teams. Ambiguously owned pieces of code see the most neglect.
Fortunately, there are ways to increase clarity-based ownership.
First, to further extend the house metaphor, we can create a 'cleaning rota' to explicitly state ownership. This might take the form of an assigned Jira ticket, GitHub's code ownership feature, or written-down rules.
Second, you might consider reducing the number of people working on each area of code. If too many cooks spoil the broth, how might you re-assign responsibilities so that only one or two people own each dish? Good team structures and slow hiring are your friends here.
2. Cleanliness
How clean code is to begin with is a strong determinant of how clean it stays.
We might think of this as broken windows theory applied to codebases. When things are already messy, why bother to polish this one tiny area?
Good programmers know that high-quality software is cheaper to produce. Seeing bad code gives the sense that you are on a bad project which is demotivating and distracting.
Another psychological advantage of clean code is that it tunes the programmer to spot mistakes early. A small buffer for how much messiness is allowed makes it easier to spot things that are going wrong in new code.
This is equivalent to the Lean practice of stopping the production line when there is a fault in the system. Counterintuitively, stopping everything to fix issues can result in higher output systems in the end. Issues are not allowed to slowly grind things to a halt as they accumulate.
I suggest focusing on cleanliness with great caution. Code will always be messy and exerting yourself trying to fix it instead of being comfortable with the chaos is usually the wrong path. That said, don't make a mess when it can be helped and automate cleanliness where possible.
3. Learning
When you are highly motivated to learn something, it is possible to exhibit a peculiarly strong mode of focus. Learning about a new thing properly doesn't permit sloppiness. If you produce bad code, you haven't really learned how to fully execute upon that new skill. This is somewhat of a paradox: your knowledge lacks in a particular area, so you focus and code well to the degree where the overall quality may be higher.
There is a balance here. If something is too hard, the effect can be massively demotivating and your motivation won't make up for the skill gaps. However, with too hard a task it is easy to be distracted.
4. People, Teams and Culture
The returns to pushing your cadence faster are everywhere and they compound continuously, for years...A stupendous portion of that advantage is just consistently choosing to get more done
– Patrick McKenzie, What Working at Stripe has Been Like
I suspect a disturbingly large amount of team productivity is mere choice. I've seen simply asking "Why don't we just do the productive thing?" then doing it have astonishing returns.
Of course, if productivity is largely a choice, why don't more engineers choose it? The answer, I think, is largely social. Productivity is culture and culture is hard to shape.
A smart, motivated individual almost always works better when surrounded by smart, motivated colleagues. Humans like to show off and a higher-performing peer-group raises the bar for what good work is. No one wants to let their teammates down and creating a shared sense of progress can be highly rewarding.
5. Open Source
I write better code when it is open source.
The least admirable reason for this is that I want to look like a good programmer and avoid embarrassment. Of course, the best way to look like a good programmer is to be one thus trying to look good in front of strangers is a useful hack to level up your skills.
Again, a word of caution here: you are writing code to solve problems, not show off on the internet. Maybe feeding your need to show off is a useful strategy to solve those problems, but don't confuse the ends with the means.
Writing good open source software is also helpful to others. Bearing in mind the altruistic benefits of your work can further incentivise you to produce high-quality outputs.
Lastly, not only does open source make it easier to give help, it makes it easier to receive it. When your codebase is comprehensible and facilitates isolated changes, you benefit from the help of others.
6. Tooling
Tests, types, linters, and continuous integration improve your code quality in direct and tangible ways but have psychological effects too. If you know that your tooling will shout at you at some point in the future, you'll write your code properly the first time.
This is almost like peer motivation. Just as you want to impress your teammates, you can want to impress your CI.
7. Flow and Focus
All programmers love Flow. It is probably necessary for writing good code. Yet Flow is elusive and we need to work to maintain it.
Having high-quality hardware and tooling boosts flow by reducing the lag between thought and implementation. I love Vim not so much because it makes me a faster typer, but because it makes me a smoother thinker. Conversely, the detrimental effect of slow networks, hardware, and software compound when they open up opportunities to be distracted.
Flow is largely about your environment. This means the physical environment (noise, light, ergonomics) as well as the work environment (context switching, communication culture, project management). A culture and workplace that maximise these two aspects will have profound psychological effects on developers' productivity.
The way code is written also impacts Flow. Spaghetti code is not conducive to focused coding. When you need to hold too many variables in your head, it is easy to let Flow slip.
Flow can be interpreted as the success state of many of the other psychological components listed here. For example, company culture can encourage Flow, tooling can get out of the way and cleanliness can minimise distractions.
8. User Feedback Loops
The feedback loop of talking to customers, writing code to address their needs, then shipping is a powerful motivational force.
The tighter you can get this loop the more psychologically powerful it becomes. At peak performance, you can be iterating through the process of 'listen, solve, ship' multiple times a day.
User feedback loops focus on the parts of the product that users really need and cuts out product cruft that would otherwise litter your code.
9. A Mission
A meaningful mission matters to code quality. Aiming for a lofty goal will make you work harder to solve any problem you encounter. It will give you cognitive abilities you didn't know it was possible to have.
Your mission can be small ('excel in this particular interview') or it can be large ('get to Mars') but it must be salient to you, the programmer.
A mission makes all other components line up. It is also the hardest to achieve. If you have the opportunity to follow one, take it swiftly.
Quick Links
- 'Egg organising' joins 'yak shaving' on my list of terms for unproductive behaviour.
- 20 year old ships £1k MMR product in a week with repl.it
- I'm reading lots of software metaphors into this 14th Century bridge construction video
Most new readers come from a recommendation from a friend. If you enjoy it, you can share the newsletter on social media or forward this email to a friend.
Spam filters sometimes get a little trigger happy. If you find this email in Gmail's Promotions tab or your spam folder, please drag it into you inbox and help other readers find the content.
I love hearing from strangers on the internet so if you have thoughts or feedback, or just want to say 'hello', feel free to hit 'reply' or DM me on Twitter.
See you next week,
James