# The mistakes along the way ## Whoops! It's bound to happen. Something that you thought was good didn't work the way you planned and now you're realizing that you've made a terrible error. Sometimes it's something that could have been avoided (committing in code that was meant for debugging for instance). The ones that really frighten me though are the ones that I did not expect at all. It's the side-effect from using a module in a way that you later learn wasn't intended to be used that way. It's the realization that this small module will be part of a larger module and your code isn't designed to make a smooth transition. Programmers make mistakes. The nature of our jobs requires us to be aware at all times of what is going on in multiple sections of code and no matter what safeguards we put into place we lose track of the state of our program and committed code. We rush and rely on muscle memory to pick up the slack. We deny ourselves areas where we can adequately test code because we feel we need to get things done sooner. We panic and when we panic we make mistakes. ## Avoiding mistakes Let's be clear: there's no way to eliminate mistakes. Software is too complex to be completely bug free. But what we can do is create places where we can tease out as many bugs as possible from the code before we put it out in front of others. When we have the ability to debug and test our code we get to better places of understanding what the code is doing and how it behaves under certain circumstances. Creating a model environment of the target system allows us to test our code against what we think the target system will do and how it will behave. We put a lot of emphasis on avoiding mistakes, both in programming and in programming culture. There are horror stories told of how a small bug in a program caused enormous pain for those involved. The morals of the story tend to illuminate that a simple mistake can be a costly mistake and we need to be more diligent about avoiding mistakes. All these tales do is make programmers more paranoid about making any mistakes. And when we operate in a fear-based mode we begin to panic. Telling programmers to make no mistakes is akin to telling someone not to be afraid - they then become afraid of being afraid. The only way we learn is by making mistakes. When we deprive ourselves of making mistakes we deprive ourselves of the opportunity to make mistakes. That doesn't mean we have to make every mistake that other developers have made before us (that would be a lot of mistakes). But we need to make our own mistakes in order to keep learning and to figure out where our gaps in understanding are. ## Making a model What we need instead are areas where programmers can set up environments where they can safely learn from their mistakes. We need areas where developers can feel OK about trying new things. But we also need an area where developers can test those changes and ensure that they don't have other rippling effects on other code. We also need environments that model the target system. They need to be as close as is practical to those target systems. That doesn't mean you need to make exact copies of expensive production environments, but you do need to make models of production environments that test enough of the pieces your code will come in contact. That also means keeping this model updated as systems change. Again it doesn't have to be perfect - it's only a model. But it does need to be close enough where your code will behave in a similar fashion between the model and the target environment. ## Learning from failure Sometimes we fail. Sometimes the code that we wrote isn't up to the realities of the system it's implemented on. Sometimes we push code that does something that we didn't expect and does any number of things. In all of these cases it causes discomfort, whether to us, the folks we support, or the folks we work with. I'm not going to lie. Failure sucks. It makes us feel like we're somehow less of a person because we failed. We feel inadequate and wonder how others think of us. Do they think less of us? Have we damaged our relationship with those who use whatever we've programmed? Have I damaged my relationship with my co-workers? All of these questions come at the forefront and they all stem from a desire to do our best and make sure that we don't cause harm to others. We want others to think well of us and our skills and failure amplifies whatever feelings of inadequacy we might have. We wonder if we should eve be doing this at all, or if our talents lie elsewhere. We feel like giving up. We don't usually let failure be part of the learning process. Failing feels a lot like and end-point of the journey. In school a failing grade doesn't usually mean "I need to practice this some more"; it usually means that we're going to cause shame and discomfort to ourselves and our loved ones. I think there's a huge disservice we give ourselves if we don't acknowledge that failure is part of a process and that it's OK to fail. Not everything we do will be perfect. Mistakes will creep into the best code we write. We'll slip up and deploy to the wrong system. We'll cause discomfort to others. A better approach is the one I mentioned above: allowing ourselves the freedom to have places where it's OK to make mistakes. Mistakes are how we learn what works and what doesn't work. We tend to remember the lessons of what doesn't work better than the ones that do work. Mistakes help us shore up where we lack knowledge and help us see the gaps that we have. They also are a reminder to pause a bit and not get too wound up in the urgency of things. I know that my own mistakes tend to happen when I'm rushing to meet a deadline (whether real or self-imposed). My worst mistakes happen when I'm tired and rushed, where I'm practically flailing at the keyboard trying to get something, anything, working. Allowing myself to pause for a moment, reflect on what it is that I'm trying to do, and see the uncertainty in the moment allows me the moment I need to recalibrate and refocus in the moment. ## Journaling our mistakes There's value in not making the same mistakes twice. But it also brings some self-recrimination when we realize that we've made the same mistake again. One trick that I use more infrequently than I would like is journaling. Journaling about what happened and how we fixed it is one way to explain to someone else (ourselves) what happened. Explaining what happened allows us to become a teacher to ourselves and reinforces the learning process. By explaining what happened in words that someone else will need to understand we give ourselves the ability to articulate our own thoughts about what happened and codify them. This isn't about keeping a record for posterity so we can go back and find opportunities to beat ourselves up about the past. It's a way to teach ourselves and maximize the learning process. It's about giving ourselves the freedom to be the instructor to our future self so we can be more aware when a mistake is about to happen and understand how to correct it. It allows us to focus on the moment just long enough to understand what happened, what we did to correct it, and how we can best proceed from here. It also helps us to locate where our gaps are and the next actions that we'll need to take in order to shore up those gaps. We'll talk more about journaling in later chapters but I fully recommend a journaling habit if for no other reason than it gives you a willing apprentice to teach, even if that apprentice is only yourself.