How to think like a programmer: The human part
Welcome to the inaugural post of this series, designed to help you think like a programmer! I got the idea for this series after a comment that I posted on a blog post got a good reaction, and someone asked me to express this in article form. So here we are.
This series is designed for people that are early in their programming journeys, however intermediate developers will also find this series useful to help fill in some gaps and understand what might be valuable to learn next. None of the topics will be exhaustive, but instead will be designed to get you thinking in the right direction. My goal is to get you excited about the concepts I present, and inspire you to seek further knowledge on your own. So let's get started!
Why the human part first?
When you think about programming and how to think like a programmer, your first instinct will be to look at the concrete skills required to work with code and make things run. However in this post we're going to take a step back and look at an often overlooked aspect of programming: The human part. Why? Because at the center of every program is a human being that took the time and energy to put it together. In fact, that human is a requirement for the program to come in to existence in the first place! So logically, it makes sense to consider the person writing the code when you are thinking about writing code.
It goes without saying that we are all human, but our own humanity also influences the way we approach technical work and how deeply we can think and understand things. Without considering the living, breathing, thinking part of programming (us), we limit ourselves to just a subset of our creative potential, and ultimately limit our own success. So through the following sections I would like to share some things I have found to be true. These ideas apply much more broadly than just programming, but in the world of code they are particularly true in my experience.
First off, You gotta wanna!
Perhaps the most overlooked part of being a proficient developer is that you have to enjoy the process of building things and understanding things. First and foremost, your role is to bring something to life out of nothing. You will be thinking in concepts, many of which will be very foreign when you start. You will be challenged to make things that don't exist, without a blueprint, and you will need to be creative to do so. You will be pushed to gain a deeper understanding of everything you touch, so that you can make it better and become better for yourself in the process. And to do any of this well, you must find joy in it.
Finding enjoyment in the work you are doing is critical, because without it you won't have the drive, curiosity, and perseverance required to get through the tough times of writing code. And there will be tough spots. Programming is hard. The mental anguish you can experience while looking for that missing semicolon, the heartbreak of a timeout error, or the sheer panic of an unexplained stack overflow can all be staggering, especially when you have a deadline to hit or a critical bug to fix. You'll need the grit to push through the crazy times.
It can also go the other way. Sometimes you just have to write a lot of boilerplate. It can feel repetitive, slow, and not engaging. You'll want to go do other things. It can get boring, but you need to have the will to push through the slow times.
Sometimes your code won't work the way you expect (or at all) and you won't know why. You can spend hours changing one small thing here, another small thing there, and still getting strange results. You can feel confused for days on end. You have to have the patience to work through the problem.
Sometimes a concept will simply be over your head. You have to have the humility to accept that you don't know everything, start small, and fill in your knowledge gaps the best you can.
I really don't want to scare anyone off (in fact quite the opposite), but this is important to think about, because in programming you are going to be frustrated a lot. It's the nature of the beast. You are stitching together technical concepts, each with their own limitations, into a system that can do the thing it's required to do. You might have days on end of no productivity. You might have a particularly hard problem that you can't solve. You might have crippling imposter syndrome. You might have all of these, all at once. You are not alone!
The flip side is you might have incredibly productive periods, where everything clicks and things just flow together. Problems are easier to solve, bugs are less frequent, and you are less inclined to turn away and do other things.
The number one thing that will keep you going is enjoying what you are doing.
From my experience, when I expect code to work that isn't, or I expect code to behave differently than it is, I become almost obsessive until I can understand why. (to the frustration of my wife at times!) I'll roll the problem around in my mind - sometimes for days - and turn to Google to see what others have to say. At some point, something will click or some information will surface, and I will be able to solve it or at least move in the right direction. I then have a moment of joy that I was able to overcome the problem, and go looking for another one.
And I write code because I love to write code. I find the creativity within technical limitations fascinating. I feel that all programmers should approach it like this. The money is secondary, and I should point out that I don't get paid to write code. (Someday maybe) In fact, all of the best developers I follow would continue to write code even if they weren't paid at all. In their spare time, this is exactly what most of them are doing with open source, because it's fun to them. So if you want to be great, do it for the joy of it!
Remember that you are human.
Like it or not, you have basic needs that you must attend to for peak performance. Sitting in front of a computer for 18 hours straight is not meeting those needs. You need rest. You need variety. You need healthy food and physical activity. This is for everything, not just programming, but it's particularly important for people that work with code.
An example of this for me is that I frequently need to get up from my desk and just go for a walk. Sometimes it's just back and forth inside. Sometimes I go outside. Stepping back from time to time allows me to reset, and come back stronger.
I also find that the more I focus on eating healthy, getting enough sleep, and getting some exercise, the better I feel AND the better I perform when I'm working, or writing, or coding. It's all interconnected. You are the sum of all of your parts, body and mind. Taking care of each aspect in turn improves the whole.
So take the time to be good to yourself. Don't expect to learn everything in a day or build everything in a day. Don't expect good results from long hours of coding and nothing else. Don't get overwhelmed and give up, but instead give yourself the space and the time to do things right, at a pace that is natural to the way your mind works, as much as you can. Feed your mind and your body, then exercise both, then get enough rest for both. Find the balance that works and is sustainable, and you can set yourself up for continuous growth and success.
The most complex things are just big collections of simple things.....
If I asked you what your definition of a computer program is, what would your answer be?
For me, a program is a series of instructions designed to take information in, work with it, and give information back out. That's it. Simple? In theory, yes. But when you look at what that might mean in practice it can quickly become very complicated. The inbound information can be very complex, or there could be huge amounts of it, and the outbound information might need to be equally complex, and there also might be huge amounts of it. Some things might be incomplete, or malicious, or utter nonsense. You might need to efficiently restructure information that seems very foreign to you. There might be restrictions on what information can come in and when, and what information can go out and when. There might be specific reasons for code to behave a certain way, and then some parameters change and it should behave a different way. Pretty soon, the simple, "Info in, Info out" program is actually a complex monster.
How do you build something like that? You come at the problem like a programmer!
The fundamental method of solving a problem with code is to break it down into simpler problems and solve them one by one. If the simpler problems are still too complex, break them down into simpler problems. Repeat until you are able to solve each problem, one at a time. By doing this exercise you are able to build systems far larger than what you can hold in your mind at any given moment. You can account for changing conditions, and change the behavior of your code. You can create flexibility and resilience. This makes your programs more powerful, and makes you feel powerful!
But make sure you understand the big picture.
The essence of programming is that you are solving complex problems by using a collection of tools and concepts, to solve collections of simple problems, building up toward a complete solution. But before you can do this, you have to be able to back up and just look at the whole problem. This takes a great deal of patience, because your first instinct will be to start writing code and see what you can come up with. However, taking the time to really understand the problem before you work toward a solution means you are approaching it with a level of thought and maturity that allows you to develop a complete solution. In other words, you have to think about things from the perspective of how to build it, but also from the perspective of the people using it, and also from the perspective of how it fits into a larger system.
Take the standard Grep program as an example. For those who don't know, grep is a program designed to search for a matching pattern of characters based on an input. And for many people, that is enough of an explanation. They might even start implementing their own version based on this. They might be shortsighted in doing so, however.
A second view is that Grep is a program to help people find what they are looking for. The important subtlety here is the people it needs to work for. Now, I don't know if you have ever used Grep before, but if you have it's pretty clear that you can't use it without first reading a manual or instructions of some sort to get you started. It's not the most intuitive. It's likely that the people that built it were originally building something strictly for like minded people, so the layperson wasn't accounted for, and as a result they built a powerful tool that can sometimes be very confusing to use.
Where all this is going is toward this point: Before you can start breaking the larger problem down, you need to understand the problem. Not just from the viewpoint of the person writing the code, but from the viewpoint of the person using it, and how it fits into the ecosystem it will exist in. Doing this will help you build programs that people actually want to use, and that perform the way they need to perform.
Everybody learns in their own way
There are 2 very important aspects that this section needs to cover.
The first is that you need to understand what methods of learning are most effective for you. It could be through books, through activities, through watching videos, or many other methods. In programming you will always be learning, so getting a grasp on how to personalize your learning path to fit you best will supercharge your growth. Then, as much as possible, you need to tailor your learning environment and your learning plan to fit your learning style.
This means that you need to be aware of distractions while you are learning, such as outside influences and your own habits. Do you have a quite place to think and learn? Do you tend to procrastinate? Do you have all the things you will need close at hand? Do you keep getting notifications? Etc, etc.
For me as an example, I have found that I do best with a quick tutorial, and then just diving in and actively working with things. This is how I learned to write code: by getting some basics down, then getting myself into problems and getting myself back out of them. It's an unstructured approach that tends to work best with the way my mind works. For others though, a more structured approach with tutorials or books might be best. I have zero opinion on which method is better, because I don't believe one is better than another. The important thing is that you keep learning in a way that fits you.
I have also found that I do best with mellow instrumental music as a backdrop. This isolates me from the distractions around me and allows me to get in to a state of flow. I do my best work when I have long stretches of time without phone calls, notifications, or people interrupting me. This seems to be true for most people, but some people love having the energy of others around them while they work. It helps them to maintain their own energy levels and stay productive.
The end goal is always the same no matter how you go about it. You want to retain the technical knowledge you need to do the work (like how a language works and what syntax to use), but you also need to retain the higher level principles, concepts and patterns that allow you do the work in the first place. Setting yourself up for success and knowing what is most effective for you is critical to achieving these 2 milestones quickly. So take the time to understand what works from you, from methods to locations to how loud the music is when you work. Doing so will help you immensely.
The second learning related thing you need to keep in mind is that not everyone else learns the way you do!
It's all too easy to look at a learning resource you have available and think that is doesn't make sense to you or it doesn't fit the way you would like. You might even be tempted to bring that to the attention of the person that created the resource.
But before you do, make sure you consider that the resource you are using might have been designed for someone that learns in a different style, or might have been designed to target as broad an audience as possible. Things like presentation, pacing, ordering of subjects, and the depth of examples might have had a lot of thought put into them, and might be targeted to the group they connect with on purpose, and you might happen to be outside that group. I encourage you to have discussions with the creators of these resources, but keep it positive and connect with the mindset of genuinely wanting to help. They are creating for a reason: They want to be helpful themselves. With this in mind, any assistance you can provide is likely welcome and often needed for them to improve.
Another layer to this is any time you need to teach something to someone else. Try to be aware of how they learn, how fast they integrate new information, and the signs of when they are becoming overloaded. It's not always obvious, and people generally want to do well and aren't as willing to admit when they have run out of steam as you might think. Try to adjust your teaching style, pacing, and break points to the audience you have, if possible. You will learn a lot about how other people think and about communication in general this way, and it will help you to improve overall.
In short, be human about learning and teaching, and empathize with the people teaching you and learning from you.
In this post we covered just a few of the human parts of writing code. There are many more and I encourage you to continuously work on this aspect of being a programmer, and being a human in general. Understanding how to be healthy and productive will help you to live happier and achieve more.
Stay tuned for the next post in the series, where we'll dive in to the deceptive world of variables. You might be surprised at what you learn.