Rules for programmers from the known
Tags: tips, programming
Published: 2020-05-03 19:06:00

I realized I have some kind of rules like in [Zombieland](https://en.wikipedia.org/wiki/Zombieland) or [NCIS](https://en.wikipedia.org/wiki/NCIS_%28TV_series%29) when it comes to programming and working in a team. I've wanted a place where I can point others to see them so we can discuss them. These are not set in stone and I am going to modify them my whole life for sure. This is a quick version in as little words as I am able to write.

I have a strong Python background so it should not be a surprise that a lot of them have some alternative in [Zen of Python](https://www.python.org/dev/peps/pep-0020/).

1. [Every rule has an exception. But exceptions should be exceptional.](#exception-rule)
1. [The perfection is attained not when there is nothing more to add, but when there is nothing more to remove](#minimalist-rule)
1. [With great power comes great responsibility](#spiderman-rule)
1. [Don't make the user think](#empathic-rule)
1. [The assumption is the mother of all fuck-ups](#assumption-rule)
1. [Boy-scout rule](#boy-scout-rule)
1. [The truth is always quicker](#openness-rule)
1. [It's better to burn out than to fade away](#loud-error-rule)
1. [10th man rule](#10th-man-rule)

<!--
[No wasted work](#wasted-work-rule)

[Everything is possible](#everything-is-possible-rule) but at what cost

design your code “optimizing for change” rather than trying to predict the future and enforcing behaviors

https://www.deconstructconf.com/2019/dan-abramov-the-wet-codebase
https://jesseduffield.com/beginners-guide-to-abstraction/

97 things every programmer should know - the book
-->

#### Every rule has an exception. But exceptions should be exceptional.<a name="exception-rule"></a>
This is the most important rule because we should not apply every rule blindly to every situation. We should think in the context. In the same way, we can't apply a design pattern on a problem without tweaking. And in the same way, the ambulance is not waiting on the red light. Also, see [ZEN#8](https://zen-of-python.info/special-cases-arent-special-enough-to-break-the-rules.html#8) & [ZEN#9](https://zen-of-python.info/although-practicality-beats-purity.html#9)

#### The perfection is attained not when there is nothing more to add, but when there is nothing more to remove<a name="minimalist-rule"></a>
I didn't come up with this one. [Antoine de Saint-Exupéry](https://en.wikipedia.org/wiki/Antoine_de_Saint-Exupéry) did. And for a good reason. The more I do the stuff I discover to do the minimal *valuable* stuff is always the best thing I can do. Why? The worst thing you can do is try to predict a future and peoples' minds and implement a little feature not needed now but "in the future". After a year, someone asks you about the code and you don't remember what it does, why it was added, and in *an ideal scenario*, you decide to remove it anyway. What you remember for sure is that it caused some bugs in the past and everybody disturbs you all the time asking about why it is there. Other people have learned that too. I believe [MVP](https://en.wikipedia.org/wiki/Minimum_viable_product), [Agile](https://agilemanifesto.org/principles.html), [ZEN#3](https://zen-of-python.info/simple-is-better-than-complex.html#3) & [ZEN#4](https://zen-of-python.info/complex-is-better-than-complicated.html#4) are variants of this rule. It's always better to [eliminate the problems than solving them](https://kentcdodds.com/blog/don-t-solve-problems-eliminate-them). Unfortunately, [complexity sells better](https://eugeneyan.com/writing/simplicity/).

#### With great power comes great responsibility<a name="spiderman-rule"></a>
You know this one the [Spiderman rule](https://en.wikipedia.org/wiki/With_great_power_comes_great_responsibility). It is quite simple. The more you can do the more you can damage. If you have access to the production DB, SELECT the rows you are going to delete. Make a backup right before the operation. If you have the root access to some servers, understand every shell command deeply before you execute it. Pasting commands from StackOverflow without knowing what they mean is not a good idea.

#### Don't make the user think<a name="empathic-rule"></a>
Or I would say *be empathic to the user*. There is a whole [book](https://www.goodreads.com/book/show/32061745-dont-make-me-think) about this. We, programmers, tend to forget that all we do should have value for the user. It shouldn't have value only for us as some hard technical puzzle to solve. And yes, the *programmer using your library/class/function is the user* too.

#### The assumption is the mother of all fuck-ups<a name="assumption-rule"></a>
Or also, "To assume means to know nothing" are my old memories of my young me watching cool action movies in the night :) I believe Steven Seagal was trying to say to the future programmers that we should write more tests. Especially when we are fixing the bug it's really easy to practice TDD. I mean, you write the failing test for the bug, you use the debugger to find the cause, and then you fix it to make the tests pass. This way you don't need to guess if the bug is really fixed and the fix covers all the cases. The tests tell you.

Another example is something that is called [Defensive programming](https://en.wikipedia.org/wiki/Defensive_programming). Don't guess how the piece of code will be used. Do everything that you can to make it work or fail quickly and loudly. But as always remember rule #1. Don't try to assert every parameter's type in the dynamic language, for example. If you want static types, use the language that supports them. If you use dynamic language simply accept it as it is (or use Typescript, Mypy in this case :)

The last sub-rule of the family is [Principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment). Don't try to be clever in the code. Try to be predictable, readable and the least surprising you can. Remember that if there is something that people (including the future you) may forget they will always forget. The best thing is to do everything as intuitive as it can be and crash with a helpful error message as [ZEN#12](https://zen-of-python.info/in-the-face-of-ambiguity-refuse-the-temptation-to-guess.html#12) whisper us.

#### Boy-scout rule<a name="boy-scout-rule"></a>
This is one of the "rules" from the great [book 97 Things Every Programmer Should Know](https://www.goodreads.com/book/show/7003902-97-things-every-programmer-should-know). If we want to fight the technical debt we need to take it seriously. It may seem to be the opposite of the *If it ain't broke, don't fix it* rule you can read here and there on the internet but that's not true. As always there is a balance. We don't want to touch the working code only to make it nicer. But if we can't even understand the code to fix a bug or add a small feature then we should probably clean it up first even if it's not directly connected. The best is when we add tests first and then refactor the parts we want to understand. The changes should be small and incremental and at the end of the day (or year) we find out we [fixed all the windows](https://en.wikipedia.org/wiki/Broken_windows_theory).

And the unused code? Commented code? Comments without any added value? Delete all that noise. Git will hold it anyway if you will need them. And most of the time you forget them. If you need to comment code out with a reason, add a comment about why it should stay and when it can be safely deleted. The same way as there would be probably the message about why the old box full of trash is in the wood if there is a reason for it.

#### The truth is always quicker<a name="openness-rule"></a>
Another [wise old "man"](https://worldofcarsdrivein.fandom.com/wiki/Smokey) told this in the [Cars 3 movie](https://www.imdb.com/title/tt3606752/). This is not a kind of universal rule, because it's more about personality and is tough for many people. One man once told me I practice *Extreme openness* (in a good way). It's easy to take the rule too far and be rude without the benefit. I can't say I never step over the line (who didn't?). But still, I think we should simply not hide reality just because it's not nice for some (or all) people in the room. I believe that if something is broken, the deadline is nonsense or the solution is not possible to achieve in a reasonable time/cost we should tell that out loud and don't promise anything just to be nice. I have to warn you - be prepared to be told you should be more optimistic. And also be prepared that other people will apply the rule on you. I will never know what is tougher - tell the truth or hear the truth :)

#### It's better to burn out than to fade away<a name="loud-error-rule"></a>
Another known person [Kurt Cobain wrote](https://en.wikipedia.org/wiki/Hey_Hey,_My_My_(Into_the_Black)#Quotations) this.  Unfortunately, not a happy recall but that always reminds me how much damage it can do (see [rule #1](#exception-rule)). Even [ZEN#10](https://zen-of-python.info/errors-should-never-pass-silently.html#10) has its antipole in [ZEN#11](https://zen-of-python.info/unless-explicitly-silenced.html#11). The tricky part is in the context. Even when most people tell you it's better to throw an exception immediately when something is wrong and `try` with empty `catch` is a bad idea, sometimes it's a good way to go. And Python has a [nice construct to explicitly suppress the error](https://docs.python.org/3/library/contextlib.html#contextlib.suppress).
```python
with suppress(FileNotFoundError):
    # if it's deleted already it's what we wanted - treat it like a success
    os.remove('temporary-file.txt')
```

The problem is that people tend to take it too seriously when they incorporate the rule into their mental model. And the fact the linter/IDE warns you about generic exceptions is not a help. The code below is quite a representative. My IDE gives me a warning about *too broad exception* and someone may argue we should let the exception inform us about the problem. But from the user point of view, it does not make sense to stop processing all the 50k products in the stock just because one is somehow broken. Also, we will see the problem in the log and can fix it anyway.
```python
domain_errors = []
for product in parse(resource):
    try:
        errors = process_product(product)
        domain_errors.extend(errors)
    except Exception:  # exception is too broad
        logger.exception('Unexpected error during processing of the product %r', product)
```

The rule of thumb could be. *Silence the errors only if you can easily recover and continue as it would happen nothing.*

#### 10th man rule<a name="10th-man-rule"></a>
Or why the person with the opposite opinion is the most important one. People of Israel from [World war Z](https://en.wikipedia.org/wiki/World_War_Z) teach us every time we see the movie. Don't reject the idea just because all others have different opinions. Or because it seems absurd at first sight. Try to understand the reasoning of the person behind the idea/opinion and don't be afraid to admit a mistake. You don't want to argue about every silly thing. But if there is some bigger impact or if there is anybody who takes the courage and tells the unpopular opinion then it's probably something worth thinking about a little.

The original rule is: If the first 9 dismissed an issue or potential danger to the ~~country~~ code/architecture/process/..., then the 10th man was forced to overrule them on principle and look into the issue no matter how far-fetched the scenario.

And Daniel Kahneman explains why. That way we can be always prepared for black swan events. Most of us view the world as more benign than it really is, our own attributes as more favorable than they truly are, and the goals we adopt as more achievable than they are likely to be. We also tend to exaggerate our ability to forecast the future, which fosters overconfidence.

There are more people with rules like me. Look:
* https://dev.to/albinotonnina/the-most-gratifying-work-i-ve-ever-done-35c7