What Makes a Good Programmer?

What makes a good programmer? It’s an interesting question to ask yourself. It makes you reflect on the craft of software development. It is also a good question to ask your colleagues. It can trigger some interesting discussions on how you work together. Here are five skills I think are crucial to have in order to be a good programmer.

1. Problem Decomposition

Programming is about solving problems. But before you write any code, you need to be clear on how to solve the problem. One skill good programmers have is the ability to break the problem down in smaller and smaller parts, until each part can be easily solved. But it is not enough simply to find a way to solve the problem. A good programmer finds a way to model the problem in such a way that the resulting program is easy to reason about, easy to implement and easy to test.

Some of the most complicated programs I have worked on were complicated in part because the implementation did not fit the problem very well. This led to code that was hard to understand. When the problem is well modeled, I agree with Bernie Cosell (interviewed in the excellent  Coders at Work):

…there are very few inherently hard programs. If you are looking at a piece of code and it looks very hard – if you can’t understand what this thing is supposed to be doing – that’s almost always an indication that it was poorly thought through. At that point you don’t roll up your sleeves and try to fix the code; you take a step back and think it through again. When you’ve thought it through enough, you’ll find out that it’s easy“.

2. Scenario Analysis

Good developers have the ability to consider many different scenarios for the program. This applies both to the logic in the program, and to the internal and external events that can occur. To consider the different paths in the logic, they ask questions like: What happens if this argument is null? What if none of these conditions are true? Is this method thread-safe? To discover what types of events the software needs to handle, they will ask questions like: What if this queue becomes full? What if there is no response to this request? What if the other server restarts while this server is restarting?

The good programmers ask themselves: How can this break? In other words, they have the ability to think like testers. In contrast, inexperienced programmers mostly only consider the “happy path” – the normal flow of control when everything goes as expected (which it does most of the time). But of course, the unexpected inevitably happens, and the program needs to be able to cope with that.

3. Naming

Programming consists to a large degree of naming things: classes, methods and variables. When done well, the program becomes largely self-documenting, meaning that the function of the program is quite clear just from reading the source code. One effect of self-documenting code is that it naturally leads to many smaller methods, rather than a few large ones, simply because then you have more places to put meaningful names (there are other reasons why many small methods are good too).

Coming up with good names is much harder than it sounds. I like this quote (from Phil Karlton): “There are only two hard things in Computer Science: cache invalidation and naming things.”  Partly naming is hard because it needs to be clear in your mind what each name represents. Sometimes that is not immediately clear, but only becomes apparent as the development proceeds. Therefore, renaming is just as important as naming.

Naming things well also includes coming up with concepts to be used, and what these concepts should be called. By having well-thought out, distinctly named concepts that are used consistently (in the program, and when discussing the domain with programmers and non-programmers), writing the program becomes much easier.

 4. Consistency

Perhaps the biggest challenge in programming is managing complexity. Consistency is one way to combat complexity. It reduces some of the complexity by allowing us to see patterns and infer how things are named, used and handled. With consistency, we don’t need to use brain power to remember exceptions and random variations. Instead we can concentrate on essential complexity, not accidental complexity.

Consistency is important across the board. It applies to variable names and grouping, method naming, the division into modules, the directory structure, the GUI, error handling, logging, documentation etc. For example, if some variables are related and appear together (in declarations, method calls or as columns in the database) then always use them in the same order. Then it becomes easier to see if one is missing, or if they have been mixed up. For an operation, if it is called delete in one place, don’t call it remove in another place – stick with the same name. Steve McConnell also has some good advice on using opposites precisely in Code Complete. For example, begin/end are opposites, as are start/stop. Don’t mix names from different pairs (for example using begin/stop) when dealing with opposites.

Inconsistencies can get introduced when modifying a program. Sloppy programmers don’t pay attention to if what they add is consistent with the existing code or not. Good programmers are relentless in ensuring that seemingly small details are just right. They know how important consistency is in the overall fight against complexity.

5. Learning

As a software developer, you are constantly learning. Before adding a new feature, you have to understand what it is supposed to do. Before adding code to an existing program, you usually have to learn what the existing code does, in order fit the new functionality in properly. You also have to learn about the surrounding systems, in order to interface with them correctly. The ability to learn fast therefore makes you a much more effective developer.

Furthermore, because the pace of development in the software engineering field is so high, there is a steady stream of new languages, tools, techniques and frameworks to learn about. You can view this as good or bad. Fred Brooks lists learning as one of the joys of the craft, and I agree. Learning new things is satisfying in itself. It also means that life as a developer never is boring.

Conclusion

All of the above skills are generic – none of them are specific to any one language, framework or technology. If you have them, you can quickly learn a new language or tool, and write good software in that environment. Furthermore, because they are general in nature, they will not become obsolete in a couple of years.

These are my answers for what makes a good programmer. What do you think makes a good programmer? Let me know in the comments.

22 responses to “What Makes a Good Programmer?

  1. You forgot the three most important skills a programmer needs: communication, communication and communication.

    • I agree, communication is crucial! I think both “naming” and “consistency” can be thought of as communication (through code).

      • I was actually referring to communication with stakeholders. The ability to understand what they want; being able to clearly communicate the possibilities, limitations and alternatives… Those are usually much more valuable skills than coding. And I say this with some sorrow, because it’s the aspect of my job that I like the least. :-(

      • Usually what happens for me before I start coding is that there are several cases (from the scenario analysis) that haven’t been specified by the stakeholders. So then I talk to them, and we work out what should happen. This is usually quite enlightening for all parties, and the problem becomes more clearly defined. I actually enjoy that part quite a lot, because it makes me learn more about the domain.

  2. Glad I found this post on Google+. I’m a fairly inexperienced programmer, but really looking to get into programming much more heavily. I’m going to encourage myself to implement these 5 skills in all programs I create.

  3. I’ve been programming computers for 40 years…old computers…new computers…big…small…

    you name it.

    I agree with everything you’ve written.

    The only thing I would add would be good visualization skills.

    I’ve been blessed (or cursed) with the ability to get a “picture” in my head as to how I’m going to solve a programming problem and that “picture” guided my code as kind of a blueprint to get the job done.

    • Great comment! I also think about my programs in pictures a lot.

    • Since a large portion of the brain is used in vision it makes sense that effective programmers would visualize their solutions. I find one big difference between junior and senior developers is their ability to “see” how their code fits into the rest of the system. I think the author addressed that in points 1 and 2.

  4. anonymous coward

    I think the most important one (not listed) is knowing what the problem is.

    • no, a Good developer Doesn’t have to know what the problem IS,
      he has to have the ability to know how to search and find a solution for it!

      if you have that skill, then that turns into existing knowledge, also known as experience! but this comes AFTER the search! ;-)

    • I think the author wrote specifically about that when he said that unnecessarily complicated code comes from misunderstanding the problem. It’s a very good reason to be constantly learning so that every problem doesn’t look like a nail because all we know how to use is a hammer! Metaphorically speaking of course. :)

  5. I think we have to consider a way back to change last thoughts and actions. A simple problem suddenly or gradually becomes hard, often.

  6. Decomposition is critical. While learning a new programming language a fellow student calculated a problem would take 6 months on the computers we were using. 1. Seemed long. 2. Seemed suspicious. Came up with my own solution, hadn’t the faintest how to estimate how long it would take because I’d be using deterministic logic. (Use logic to evaluate a step before advancing to the next step) Solves in 2 minutes on my machine so should solve in 8 minutes on the old computers we were on. (I can alter the deterministic logic so it will solve in 8 minutes. I can alter the problem so it solves in milliseconds.) I also came up with the worst design I could think of and that one I could estimate at a quintillion years.

  7. After the ability to deliver high value solutions, and I do agree with the points raised from that perspective; rate and reliability of delivery surely follow as the multiplier to single out the truly excellent.
    Among the characteristics tending to differentiate such developers are:

    – excellent memory
    – attention to detail
    – consistently methodical
    – self disciplined

    The greater the mastery of these, the sooner and more reliably goals are reached.

    Employers value a consistent (reliable) high rate of delivery with good quality and minimal defects.

    While other factors play their part, personality and teamwork for example, for the individual developer these are key. The skills in the article seem that they may be learned more easily than these more deeply ingrained traits, particularly memory; making these rarer and thus more highly prized.

    It’s easy to overlook these simple qualities in a developer, they are comparative and require time to assess while the skills stated in the article though hard to quantify are surprisingly evident under brief examination of a masterful lead developer.

    Managing risk and ensuring consistent delivery pays a big part in managing software projects. Ultimately who would you choose to go on your team? Life is difficult enough.

  8. It could probably be included in consistency, but I find formatting an important ingredient. Code is so much easier to read if it all lines up.

  9. Excellent article (speaking with 30 years programming experience behind me ;-))
    There is however one fundamental word that is missing: *abstraction*
    “Good programming is the art of discovering the best abstractions to solve a problem and capitalize later on it.”. Then you need to name them properly, expose them, etc…
    That’s what I have found out when looking at code from “good programmers”.

  10. Pingback: Qu’est-ce qui fait un bon développeur ? | Fier d'être développeur

  11. How about sizing? The ability to size the problem that needs to be solved. I would say that belongs in the top 5 skills to be a good programmer. Nothing more frustrating than a programmer that can’t size his work, and either under/over delivers.

  12. Pingback: Links – July 2014 | Ninad's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s