Code that Fits in Your Head
Table of Contents
Notes from the book: Code That Fits in Your Head - Heuristics for Software Engineering Mark Seemann (2021)
1. Metaphors are incomplete
1.1. It is building
1.1.1. Software is not a project
@ Because it never ends.
If you think of developing software as being similar to building a house, the first mistake you’ll make is to think of it as a project. A project has a start and an end. Once you reach the end, the work is done.
Only unsuccessful software ends. Successful software endures. If you’re fortunate enough to develop successful software, when you’re done with a release you’ll move on to develop the next. This can go on for years. Some successful software lasts for decades1.
1.1.2. High performing teams can release any time
@ Based on research, the book Accelerate [29] argues convincingly that the key capability distinguishing high-performing from low-performing teams is the ability to release at the drop of a hat.
1.2. It is a craft
@ It seems compelling to view software development as a craft, as essentially skilled work. While you can take an education in computer science, you don’t have to. I didn’t4.
1.2.1. Learn faster by moving from code base to code base
@ You can learn faster by moving from code base to code base. Try some back-end development. Do some front-end development. Perhaps try some game programming, or some machine learning. This will expose you to a wide range of problems that will accumulate as experience.
This is strikingly similar to the old European tradition of journeyman years. A craftsman like a carpenter or roofer would travel around Europe, working for a while in a place before moving on to the next. Doing so exposed them to alternative solutions to problems. It made them better at their craft.
1.2.2. Its not art
@ The problem with the viewpoint that programming is an art is that it doesn’t seem to scale. In order to ‘create’ new programmers, you’d have to take them on as apprentices until they have learned enough to become journeymen. From there, mastery is several more years away.
Another issue with viewing programming as an art or a craft is that it, too, doesn’t fit reality. Around 2010, it began to occur to me [106]that I was following heuristics when I programmed—rules of thumb and guidelines that can be taught.
1.3. Aspire to be an Engineer
- @ ‘Real’ engineers follow methodologies that usually lead to successful outcomes. That’s what we programmers want to do as well, but we have to be careful to copy only those activities that make sense in our context.
- @ Software engineering was developing but everybody got PCs and thus it was derailed
- @ Engineers also do creative, human work, but it’s often structured in a framework. Specific activities should be followed by other activities. They review and sign off on each other’s work. They follow checklists [40].
@ Purpose of software engineering is to enable you to make changes at a sustainable pace.
You can do that as well.
2. Use checklist as aid for memory
@ A checklist is just an aid to memory. It doesn’t exist to restrict you; it exists to help you remember to perform trivial, but important actions, such as washing your hands before surgery.
2.1. Trick: Add an empty initial commit
< Collapse code block
git commit --allow-empty -m "Initial commit"
@ I usually do this because it enables me to rewrite the history of my repository before I publish it to an online Git service. You don’t have to do this, though.
2.2. Use linters, treak warnings as errors
2.3. Hack your organization
@ When you’re facing pressure to ‘just deliver’ because ‘we don’t have time to do it by the book’, imagine replying,
“Sorry, but if I do that, the code doesn’t compile.”
Such a reply has the potential to curb stakeholders’ insistence on ignoring engineering discipline. It’s not strictly the case that you can’t possibly circumvent any of those automatic checks, but you don’t have to tell everyone that. The stratagem is that you turn what used to be a human decision into a machine-enforced rule.
3. Write code with value
@ The term value is often used as a proxy for purpose, despite the fact that you can’t measure it. There’s a school of project management based on the idea [88] that you should:
- form a hypothesis about the impact of the change you’re about to make
- make the change
- measure the impact and compare it to your prediction
This isn’t a book about project management, but that seems a reasonable approach. It fits the observations of Accelerate [29].
The notion that code should produce value unfortunately leads to the logical fallacy that code not producing value is prohibited. The notion that worse is better isn’t far off.
3.1. Improve readability of code
- You spend more time reading code than writing code
- Fixing bugs require you to understand the code i.e. read
- Every minute you invest in making the code easier to understand pays itself back tenfold. @
- @ Programming is not all deliberate thought (system 2), it is also System 1. But System 1 only works better if all relevant information is right in front of your eyes.
- So, keep relevant code together
- Avoid global variables and hidden side effects
3.2. Software Engineering vs Computer Science
@ CS isn't Software Engineering just as Physics isn't Mechanical Engineering
4. Vertical Slice
- @ Start with working software
- Implement a vertical slice of it (i.e. a feature),
- deploy it, test it
- get feedback from stakeholders
4.1. Avoid speculative Generality
@ You should avoid Speculative Generality [34], the tendency to add features to code because you ‘might need it later’. Instead, implement features with the simplest possible code, but look out for duplication as you add more.
Find a motivation for making changes to the code. Such motivation acts as a driver of the change, so to speak. E.g. linters and compilers are also drivers of change.
5. Command Query Separation
@ It’s much easier to reason about APIs if you keep Commands and Queries separate. Don’t return data from methods with side effects, and don’t cause side effects from methods that return data. If you follow that rule, you can distinguish between these two types of functions without having to read the implementation code.
6. Type > Method Name > Comment
@ Don’t say anything with a comment that you can say with a method name. Don’t say anything with a method name you can say with a type.
7. Make Routine
7.1. Code Reviews
- In the morning
- Or after lunch
Because those times are natural break period. And you can make a habit of code review after that time. You could set aside time befor lunch, but mostly you'd be doing other things.