Software Development Lessons Learned from Poker
I wasn't always a software developer. The two years before I joined ThoughtWorks I lived primarily off playing poker. Of course, if you've ever asked me about the tattoo on my forearm, you've already heard the story. If you haven't, feel free to ask me next time we get a drink together.
I've never regretted spending so much time playing poker. I believe it taught me quite a few lessons that apply widely to other topics. In fact the more I develop software the more I'm convinced that the two jobs are incredibly similar.
I approached learning poker the same way I approached learning software development: read as many books as possible. Over the course of 2 years I read every book on poker I could find. I stopped counting at 39. Of course, the same can be true for programming. I have 5 books in front of me right now that are queued up to read next, and I have a large collection of books that I've burned through in the past 3 years with ThoughtWorks.
I consider reading books, blogs, and magazines to be essential for both programming and playing poker, but in both professions reading books isn't good enough. You may be able to keep all the knowledge in your head, but knowing when to apply which rules is the mark of a true professional.
Reading material is great for learning, but it's almost always the context that determines when to apply a certain technique. Since books cannot be specific enough to provide all possible contexts, only experience can give you the ability to be able to make a quick decision that could end up costing you or your employer thousands or even millions of dollars.
There truly is no replacement for experience.
Art at the highest level
You can design a computer program to beat an average poker player. By following basic rules you are guaranteed victory. However, to this day there are no programs that can beat the best poker players. This is because at it's highest levels poker is an art. Of course, the same is true for software development. To become an average developer all you need is a catalog of best practices. If you follow the cookbook you are almost guaranteed to create an average application. Truthfully, that's better than the most common alternative. So many projects fail that, I believe, most managers would gladly pay for an average application.
Of course, some managers have higher standards. At banks, start ups, medical systems, etc the stakes are much higher. Average isn't good enough. These managers are willing to pay for the best and they expect a much higher level of skill. The problem is, expert developers have a different skill set than average developers. Average developers know how to do something, experts know why to do something. Average developers follow patterns books like they are cookbooks, expert developers understand that innovation applied to patterns can lead to exponential performance gains.
Expert developers have such a different view of the world, it can be hard for average developers to interview experts. Being an art critic is easy, being a good art critic is very hard.
One thing is absolutely true about both poker and programming: almost no one is as good as they think they are. Knowing that you aren't as good as you think you are is a good first step, but it's hard to know how much better the experts are. Programmers are rarely exposed to enough experts to fairly judge their own skill level. At the poker table everyone gets together for tournaments, but I'm always very surprised by how highly most people rate their abilities.
The same is true of programmers, but most of them have even less information to work with. The technical leader who never attends a conference has only his team members to compare himself to. Of course, he's the tech lead, so chances are he's already the best. But where does he stand compared to the talent level of the rest of the industry? If he believes he is already on the top of his game, what happens when he meets someone with different opinions? Some are excited about the prospect of learning, but most dismiss contradictory ideas to their own as silly.
To the casual observer poker appears to be a game where it's everyone against everyone. In fact that's rarely the case. Even at the low stakes tables there are generally at least a few people who know each other. These acquaintances don't make deals to take on the rest of the table, they don't have to. It's understood that you don't make money playing poker against people who are good, you make it by playing with them to take the it from those who are not. Professional poker players work even more as a team. Several of them own percentages of each other, thus if any of them win, all of them win. They don't stop by knowing only each other, they know everyone. The floor manager can call them when a good game is going on. The waitress can make strong drinks for their opponents. The dealers can make "mistakes" to upset certain players (rarely do people play well when they are upset). Everyone works together to ensure that everyone gets paid.
Programming is interestingly similar. Many programmers sit in cubes, tackling problems all on their own. These programmers often work with a strong code ownership model. I've seen these developers deliver applications, but integration is almost always a pain point. Unfortunately, integration pain is often the smallest problem. Consider an IT department that locks the business to a 500 page requirement specification. If the business needs to change direction there's often a very painful change request system put in place. Millions are wasted as programmers build features that the business no longer needs, but IT departments haven't found a better way to work with their businesses.
Of course, it doesn't have to be this way. Experts collaborate. Experts collaborate with other expert developers, but also with their managers, customers, business, analysts, quality assurance, and any individual who can contribute to their success. Experts understand the bigger picture: working together ensures everyone gets paid.
Aspiring poker players often talk about how many hands they won or lost. Mostly, they talk about hands that they should have won but lost. Sometimes people make mistakes and lose, but they don't usually remember those hands. Conversely, they seem to remember every single detail of each hand they've ever lost where they were simply unlucky. The stories often contain the percentage chance that their opponent had to win. Poker players know how many hands they've lost, and what their chances were to lose. Poker players know metrics. However, professional poker players know to focus on the metrics that matter. It doesn't matter how many hands you win or lose, it matters how much money you win or lose. Furthermore, worrying about your bad beats actually translates to worrying about the poor performance of your opponents. Since you profit from your opponents mistakes, you are essentially complaining about your opponents giving you their money.
Having metrics is good, but professionals know which metrics are important, which are simply noise, and which fall somewhere in between.
Software development also contains many metrics, and many of them receive much more attention than they should. For example, it's very hard to get much value from knowing the number of lines of code. Complex applications require a fair amount of code, but what's fair? It depends on the language, tools, and any number of other factors.
The number of bugs fixed is another less than interesting metric. Why does it matter how many bugs have been fixed? The number of bugs might be valuable, but knowing how many are fixed doesn't really tell us much.
My personal favorite is feature complete percentage. Unless features are estimated for level of effort then knowing how many features have been completed doesn't really tell you much of anything. And, if you already measured level of effort, then why not measure effort of things done with things that aren't done to show progress. It's tough for me to see any value in the feature complete percentage.
Code coverage is a metric that reminds me of keeping track of your bad beats. There's value in the metric, but most people miss the point. Having a low code coverage number means you probably do have a problem, but having a high code coverage number means nothing more than you have a high code coverage number. High code coverage cannot ensure high quality.
People, not Logic
If you've seen any movie with poker in it, you've likely heard: You don't play the cards, you play the person. This is very true. Poker is in incredibly psychological. Sure, you needs cards some of the time, but getting good cards is only part of making money. Once you have good cards, you need to know what to do with them. Should you raise, check-raise, or simply check or call. This choice depends on many factors, but the central factor is knowing the people you are playing against. When you get good cards, your number one goal is to make as much money as you can off of them and the only way to know how to get more money is to know what actions will make your opponents give you more money. Logic helps you win hands, knowing people helps you win money.
People are equally as important in delivering software. If software were simply about making things work, it would be much easier to automate. But, software is about so much more than groups of features. It's about software packages sold over a game of golf. It's about contracts signed during a complimentary trip for the family to Disneyland. It's about fulfilling contracts for software that's no longer needed, to avoid yet another lawsuit. It's about business that needs to change at a rate faster than their competition.
Software development is about every variable related to every person in every organization that uses, developers, maintains, or relies in some way on that one piece of software. There are simply too many variables to apply simple formulas and produce quality software. Instead, the expert software developer needs to take into account all the known and unknown variables that each person introduces and make their best guess. It's helpful to know what you should do, but it's priceless to know what you must do. Logic helps you deliver applications, knowing people helps you deliver value.
Working with Incomplete Information
Beginner poker players have it very easy. Play good hands, always bet, never bluff. That's it, you really shouldn't do anything else while you are first getting started, unless of course you have a bunch of money you want to give away. It's moving up from the beginner level that really is hard. There's so much information coming at you all at once. You need to pay attention to the attitudes of everyone at the table, how they are interacting with each other, what your history is with each individual opponent, what kind of hands they like to play, who's winning, who's losing, and a million other variables. Also, you can't know for sure what the other players are holding and what the next cards are going to be. You have more information than you can handle, and still not all of it.
Programming is no different. Domain experts hold all the knowledge, but it's inefficient for them to try to give you all that domain knowledge up front. Furthermore, you may not need all that domain knowledge. You also need to know your team well, but there are things about your teammates that you will never know or fully understand. Yet, expert programmers can digest necessary domain knowledge, understand their team's dynamics, and consistently provide technical vision. Expert programmers understand that they will never have the entire picture, and they also understand which things are worth considering, and which things need to be disregarded. Despite overwhelming and incomplete information, expert programmers consistently make correct decisions.
Average poker players are better off in poker games that provide less feedback. This is because poker players win money based on information. In a 5 card stud game there is only one round of betting. Only one round for someone to exploit information you've given them and only one round for you to make a mistake. Expert poker players prefer poker games with many rounds. The more rounds there are in a poker game, the more times an expert has an opportunity to exploit a less skilled opponent. Expert poker players appreciate immediate feedback and the ability to vary their play based on that feedback. Poker games with several rounds give you feedback in each round, at which time expert poker players alter their play to fit the current situation.
Expert software developers also value immediate feedback. Immediate feedback from the business can save you from building the wrong domain concept into an application. Immediate feedback from another programmer can point out a bug before software moves to production. Feedback by way of a Continuous Integration server can provide immediate integration feedback, thus easing integration pain. If you prefer Agile, you'll immediately point to Iterations as an obviously beneficial practice of giving both programmers and the business immediate feedback. However, even if you don't agree with Agile, an expert programmer recognizes the value of immediate feedback. Even if you work in a non-Agile environment, an expert programmer seeks as much feedback as possible to avoid wasted time and effort. Immediate feedback lets you know if you are headed in the right direction, and every expert appreciates that information.
Context is King
With poker and programming there are few right and wrong answers. Should you fold Kings before the flop? Maybe. It depends on if you in a tournament or cash game, is it limit or no limit, what seat are you in, has it folded to you already or is it already capped, is the game wild or is it full of rocks, and on and on. One thing I learned about poker is that all those factors and many more must me considered before giving your answer.
The more I program the more I realize the exact same lesson applies to programming. In some situations Java is a good choice, but not all. Of course, the same can be said of almost any programming language. This is true of tools also. Hibernate is great, until it isn't, then maybe IBatis is great, until it isn't and then a new solution needs to be found or crafted. Almost no solution is simply a good thing, instead it's a good thing given the right situation. Given the wrong situation it's a horrible idea.
So, before you dismiss or evangelize your next language or tool, please remember: It depends...
Hit the spot
I am a bad poker player, and a possibly overvaluated IT professional. And somehow I am using poker as a replacement fon negotiation training (which from now on will include serving heavy drinks to my opponentes).
A couple of issues really hit the target, like "you can't claim you are an expert if you never met a real one..." and the fact that there are metrics hat matters and other that don't. Also, poker has a "lifecycle" which makes you play very differently at the beginning an at the end.
Unfortunately, in software development one has not so many chances to "fold" as it happens on thepoker table, and this is probabily the biggest and saddest difference. :-(
Quite a different kind of teamwork
Expert developers collaborate "with other expert developers, [...] managers, customers, business, analysts, quality assurance, and any individual who can contribute to their success". I think they should collaborate with anyone who can contribute to the success of the team or the project, and that usually includes less expert developers as well.
Maybe my point of view is different just because I used to play rugby rather than poker? :-)