Larry Wall once said that the three virtues of a programmer are Laziness, Impatience and Hubris. This saying has become legendary tidbit of software development humor. And as all good jokes, this one is funny because it is mostly true.
I think we can all agree that laziness can be most definitely a virtue when it comes to programming. Writing software is not about working hard, as it is about working smart. This always reminds me of the tenacious, hard working students I used to encounter when I was a TA for the introductory Java classes back in grad school. There were few of those each semester, usually coming from Math/Science background taking CS the low level courses to fulfill some curriculum requirements. They were usually type A personality types: organized, ambitious, very eager to do well in class. They were also the students that would do crazy stuff like copy and paste the same statement six hundred times in their code instead of using a simple loop. Whenever they saw tedious busy work it didn’t ring the usual alarm bells in their head. They would jump right into it, and plow ahead never slowing down to think there might be something wrong with their approach. It felt boring, tedious and hard and therefore in their heads it felt right – this is how work is supposed to feel, right?
But that’s not how you program. When you write code, anything that seems tedious or boring and repetitive busywork usually means you are doing it wrong. There is always an easier, more elegant way. The whole point of creating software is to off-load the repetitive stuff onto the machine. A good programmer always finds a way to avoid doing too much work by abstracting it away.
Same can be said for impatience. When you are writing code, most of the time the important thing is to get it working as quickly as possible. You don’t want to sit there and reinvent the wheel. When your goal is to build software that does X you don’t want to spend weeks or even months solving problems Y and Z that deal with sorting and searching for example. Especially since those problems have already been solved and encapsulated into modules and libraries. There is usually no good reason to build things in house if you can pull in a third party library or module as a dependency and get same results.
Naturally, if you set out to improve search algorithm, then more power to you. Or when the built in library turns out to be a bottleneck then it may need to be re-implemented. But a lazy, impatient programmer will by default look for existing solutions before writing something on their own. And that’s usually a good thing. Rather than re-inventing the wheel every day, you build on the shoulder of giants.
But there is more to this than just using existing code. It is also about building things incrementally. I’m not going to preach Agile here, but the general idea of getting things to work quickly in small increments is generally a good one. It creates a positive feedback loop – you can see your project taking shape and becoming functional quickly, and then you iterate on top of it. You create mockups and dummy models for the stuff that is not implemented yet, and focus attention on components that need to be fleshed out avoiding potential clusterfucks.
Hubris is where Larry looses me though. Hubris is actually a terrible vice – whether you are a programmer or not. There is this myth of the so called “cowboy programmer” – a genius who walks into the room, sits down and makes miracles happen. He fixes the code-base that no on ever understood; he makes that slow app run blazing fast; he saves the project during the crunch time. Too bad that guy actually doesn’t exist. Every single superstar programmer I have ever encountered was just a plain old jerk whose code was just as shitty (if not shittier) as everyone else. Their stardom was not a result of skill but of personal charisma. These guys could sell themselves well and would take every opportunity to brag about their code.
But you know what their secret was? They cut corners. They didn’t test. They made intuitive decisions that were usually only partially correct. They wrote sloppy code and optimized prematurely. All because of overconfidence and hubris. You actually don’t want that guy on your team. Do you know who you want on your team?
You want guys who lack confidence in their skill. Do you know why? Because they will test their code. A cowboy programmer makes decisions based on hunches – he believes in the validity of his code and plows forward. A cowboy programmer does not stop to fix mistakes, or worry about edge cases or special conditions. Someone who is not as confident in their skill will write unit tests to ensure they are are not introducing instabilities or bugs to the code. Hell, they might even work out a mathematical proof to show their solution is going to work.
When you are building a team you want people who ask questions. You want people who view code reviews as an opportunity to learn and improve their craft, and something necessary to improve the product: not as a face-off they must win to preserve their reputation as the top dog. You want people who won’t just re-write a critical piece of an application over the weekend because it was “wrong” but will actually try to understand why it was written this way, and what are it’s quirks. People who will track down the developers who wrote the code and actually ask them for advice and guidance rather than rip out the foundations from underneath your project and replace them with something they deem better based on a hunch and a feeling.
I guess when Larry Wall was writing Perl the times were a little bit different. The software industry was still young and still wild. There was a place there for overly confident code cowboys who could get the job done. But those times are gone, and software development has matured. We now have best practices, patterns and various competing methodologies that help us structure our work. Hubris is no longer a chief virtue of a programmer.