I Am Not Perfect.
I've been programming professionally for 25 years, and the most important thing I have learned is this:
- I am fallible.
- I am very fallible.
- In fact, I make mistakes all the time.
I'm not unique in this. All humans are fallible.
So, how do we still get our jobs done, knowing that we're likely to make mistakes in anything we try to do? We look for ways to compensate.
Pilots use checklists, and have for decades. No matter how many times they've done a pre-flight check on a plane, they review their checklist to make sure they haven't missed anything, because they know it's important, people make mistakes, and the consequences of a mistake can be horrendous.
The practice of medical care is moving in the same direction. There's a great book, The Checklist Manifesto by Atul Gawande, that I highly recommend if you haven't come across it before. It talks about the kind of mistakes that happen in medicine, and how adding checklists for even basic procedures had amazing results.
I'm a big fan of checklists. I'm always pushing to get deploy and release processes, for example, nailed down in project documentation to help us make sure not to miss an important step.
But my point is not just to use checklists, it's the reason behind the use of checklists: acknowledging that people make mistakes, and looking for ways to do things right regardless of that.
For me, I try to find ways to do things that I'm less likely to get wrong now, and that make it harder for future me to screw them up. I know that future me will have forgotten a lot about the project by the time he looks at it again, maybe under pressure to fix a production bug.
One of my favorite quotations about programming is by Brian Kernighan:
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
("The Elements of Programming Style", 2nd edition, chapter 2)
So I work hard to avoid mistakes, both now and in the future.
- I try to keep things straightforward
- I use features and tools like strict typing, lint, flake8, eslint, etc.
- I try to make sure knowledge is recorded somewhere more reliable than my memory
I also try to detect mistakes before they can cause bad things to happen. I'm a huge fan of
- unit tests
- parameter checking
- error handling
- QA testing
- code reviews
To sum all this up:
Expect to make mistakes. You will anyhow.
Plan for them.
And don't beat yourself up for it.