Can we apply the principles we use to write good code to make our lives better?
This is a bit of a special post today, that was triggered by a question someone asked when I hosted an Ask Me Anything session:
Is life and coding similar in some ways, what parallels can you draw? Are there things you learnt with programming that you apply to daily life?
On Fluent C++ I usually talk about how to make code expressive, or at most how to keep your spirits up when facing non expressive code. But everyday life? Not really something you’d expect here, is it?
But that question made me realize that if some principles are so widely applicable as to work with coding in general, maybe they can go beyond coding itself. This question made me put coding and my daily life in perspective, and I did find that some aspects of our lives can be improved with the same practices as in programming.
So let’s venture out of hardcore coding for once, and put what we know about code into practice to make our lives easier. And rest assured, in the next post we’ll dive right back into code.
This question was submitted by Rashmosh and I’m very grateful for that. Even if this open-question session is over, you can still Ask Me Anything in an email. I’ll be more likely to have an answer if your question is about coding though 🙂
Here are the parallels between coding good practices and everyday life that I have found so far.
Analyse twice, debug once
I know a doctor who complains that some of her patients come to her requesting a specific test. Something like: “Doctor, my chest hurts, prescribe me a scanner please.” Apparently, this is not the right way to treat a condition.
A better way is for the doctor to start asking questions (“Do you smoke? Do you exercise?”), then look around the patient, and based on this analysis formulate a hypothesis of what is wrong with that person (no idea what that would be here, since I’m not a doctor). Once the doctor has a hypothesis, she can prescribe a targeted test that will confirm this hypothesis. And when the test has confirmed the diagnostic, she gives the patient the appropriate treatment.
This lines up well with the fastest way of fixing a bug. The fastest way I know to fix a bug is by starting by looking a the test case that exhibits the incorrect behaviour in the application, then playing around with it until formulating a hypothesis of what can be causing the issue.
And only then, fire up the debugger to go directly to the line of code that could confirm the hypothesis. When that hypothesis is confirmed, make the fix.
On the opposite, starting by debugging right away the region of code concerned by the buggy functionality will make you spend hours trudging through lines of code before finding anything wrong – or collapsing of boredom.
The common point between those two stories – the doctor and the software developer – is that they consist in identifying the source of a problem. A heath issue is like a bug in somebody, if I may say. It appears that investing time in the analysis instead of looking inside first is the efficient way to go about it.
Clean code first, performance then
The most efficient way to ensure having an application that runs fast is known to be this: to write code as clear and well structured as possible without thinking about micro-optimizations, and if the resulting software is too slow, profile it to identify the bottlenecks. Then do something about the parts of the code that take the most time.
Indeed, most of the time is typically spent in a little portion of the code, but it’s next to impossible to guess where by intuition only.
What does “profiling” mean? One way of profiling consists in running the program with a special binary that counts how much time is spent in every function. You end up with the list of all the functions that the program went through and how much time (or more accurately, how many CPU instructions) each of them took up.
Some of the processes of our everyday life can be optimized the same way. Take the morning preparation for example. At some point, it took me a ridiculous amount of time to get ready in the morning (up to 40-50 minutes, and I don’t even take breakfast before getting out). Then one day, I decided to profile my morning preparation the same way that we profile an program.
I kept a stopwatch near me, to measure how much time every step of the preparation was taking me (shower, getting dressed, putting my shoes on, and so on). I noted the results, analysed them to find out where time went, and took action for the one or two biggest sources of cost.
Now I get ready in 25-30 minutes in the morning!
Modularity is perhaps the most transverse software development principle, as it applies in every language and at every scale of software construction. It consists in identifying the components of a system, and defining how they are allowed to interact with each other.
To keep a system sane and under control, you absolutely need its components to be decoupled from each other. Modularity helps managing complexity, because if components have too much access to each other, in particular if those accesses are not in read-only, the system becomes unmanageable.
What is interesting is that it is true at all levels: functions should be decoupled from each other, classes should be decoupled from each other, modules should be decoupled from each other, and so on.
I think this translates quite well to everyday life, because life is full of entities that can be assimilated to components of a larger system: a person, a household, an employee, a team, etc.
Some aspects of those entities are better left to themselves without unrequired access from other components. For example, it is counter-productive to judge how much sleep a person needs, or how a household that we don’t live in should deal with their finances. Similarly, we should not micro-manage employees, and teams are better off with some flexibility to organize themselves. And so on.
YAGNI stands for You Ain’t Gonna Need It, and prones avoiding to develop features “just in case” we need them in the future. Because most of the time, we end up not needing those features and they represent a burden in the code incurring a maintenance cost for no benefit.
Indeed, it is very hard to guess what a client will need in the future based on the requirements that we have today. For this reason, the YAGNI principle advocates designing minimal interfaces, that contain exactly what the client needs and nothing more.
In the same spirit are the objets that we keep “just in case” in our homes. Don’t you have some of those that are taking up space on your shelves or in your basement?
When I moved apartment I tried to throw away every item that I had no use for, and not to keep them just in case they could be useful one day. It is hard sometimes. But there is this theory that any just-in-case item can be replaced for less than 20 dollars and in less than 20 minutes. And that the vast majority them don’t ever need to get replaced anyway.
I very much adhere to this theory. Getting rid of those items bring the satisfaction of freeing up space and reducing the burden on both our software interfaces and our homes.
When designing a component, it is important that you respect some conventions in order to make it easier for its users to discover it.
Take the example of containers. In C++, the standard containers all share some methods names and some design characteristics, and your custom containers should abide by the same conventions. This way, someone who knows the standard library (and all developers should know their standard libraries in my opinion) have a head start on how to use your custom containers.
On this, the comparisons with everyday life are countless. Just look around you and see that all traffic lights have the same colours, taxis have the same way of showing if they’re available, all phones share the same layout for digits, TV remote controls have the on/off button at the top, and so on and so forth.
Like good software interfaces, these everyday objects all abide by some conventions to make it easier for us to use them.
How do you use coding principles in your life?
Do you also use best practices of programming in your everyday life? I’d love to know!
If you see a parallel between code and life, or if you took inspiration from a software technique to solve a problem, please share it in a comment below.
- Follow the conventions of the STL
Share this post! Don't want to miss out ? Follow: