Andy Hunt and David Thomas in their book “The Pragmatic Programmer” make an interesting observation about a persona Fred:
"Suppose Fred is given a programming assignment. Fred types in some code, tries it, and it seems to work. Fred types in some more code, tries it, and it still seems to work. After several weeks of coding this way, the program suddenly stops working, and after hours of trying to fix it, he still doesn't know why. Fred may well spend a significant amount of time chasing this piece of code around without ever being able to fix it. No matter what he does, it just doesn't ever seem to work right.
Fred doesn't know why the code is failing because he didn't know why it worked in the first place. It seemed to work, given the limited "testing'' that Fred did, but that was just a coincidence. Buoyed by false confidence, Fred charged ahead into oblivion. Now, most intelligent people may know someone like Fred, but we know better. We don't rely on coincidences---do we?
Sometimes we might. Sometimes it can be pretty easy to confuse a happy coincidence with a purposeful plan"
During a discussion with one of my early project Managers, a Mentor and a person I really look up to, he coined Fred’s symptoms and gave it an appropriate name – he calls this the “Junior Developer Syndrome” and feels that every programmer was once Fred.
He also describes another very important feature of Fred. According to him (I couldn’t agree more), during these “hours of trying to fix it”, this Fred guy usually doesn’t tell anyone there’s a problem.
Like all other programmers the first couple of years of my coding life went in getting rid of the Fred within me. These years also taught me lessons all of us have learnt at point in our life. This post is an attempt to organize my own thoughts and try and understand why Fred programs by co-incidence.
There are lots of other complex factors that go into software development life; however, to keep this post simple let’s consider that Fred is worried about the tree most evident factors in a software development project.
- Quality of Code.
- Time Needed to write Code.
- Pressure to ship (from Stake-holders).
I’ll just go ahead and use graphs to illustrate how these three typically play together.
The Graph Plots Time needed to code against the quality of code. Spending a little bit of more time in understanding the Technology and figuring out the “why the code works” part gives a tremendous boost to the quality of code by investing just a little bit of time. The initial tweaks and optimizations are easily achieved by spending a little bit of time on the technology and understanding why the code works and how it works. The Graph depicts this as the distance between points A and B. i.e. [AB].
The most typical example of this I’ve seen is ASP.NET caching. For example, I’ve been on projects where a 4 second Page load was brought down to 300 milliseconds by just spending a day on Caching. In other words spending [AB] time gave us a [XY] increase in the quality of code.
After you’ve spent that initial time however, the law of Diminishing returns starts to kick in and every other tweak on code takes more and more time. In the same project I mentioned earlier we spent over a week of performance tuning to bring the 300 milliseconds down to less than 150. In other words, we ended up spending [BC] time to increase the quality of code by [YZ].
Now the obvious question is if by spending just [AB] worth of time learning about the “why” and the “how things works under the hood” of the technology on which Fred is working on, if Fred can get and [XY] gain in the quality of code why doesn’t he invest that time in making his code better?
In this past couple of years I've discussed this (in one way or the other) to multiple Senior Associates, Technical Architects and Project Managers. Some have told me that Fred is just stupid. Others claim that Fred just works for a Pay-check and [OX] worth of quality is usually good enough to get the project go through client acceptance. Fred couldn’t care less about code.
Others however, mentioned a reason that sounds more likely – The third factor I talked about earlier in the post - Pressure to ship – that is what causes Fred “Program by Co-incidence”.
Notice the graph above. Here the pressure to ship show up suddenly as your product / project starts getting shape or starts generating excitement. As you move from point E to F tweaking your code, the pressure to ship slowly growing up by [PQ]. As you move from F to G and the Shipping-Date / Dead-Line / Committed Date comes closer the pressure to deliver shoots hugely by [QR].
Now let’s merge both of these graphs.
Merging these two graphs answers some of the questions and gives a new perspective into – Why does Fred write Bad code. Think about it a little more and it makes so much more sense. The problem with Fred is that he considers his code ready to ship as soon as he senses some pressure to Ship from Stake-holders. He considers his code ready-to-ship at point X. Fred wants to see the Stake-holders happy. He’s not a bad developer! Or, is he?
The other extreme are people who will not ship till point Z. People who will spend weeks to fine-tune a tiny performance issue that is causing a round-trip to take 15 milliseconds more than what it should take. This kind of a developer runs the risk of Never Shipping, because the Green curve never becomes parallel to the X-axis. In other words, no matter how much you tune and tweak your code there is always room for improvement.
So when should you ship?
During one of my first projects in my development life (when I was very young and enthusiastic :)) I shipped a project at point X and paid the price for it. The code I shipped very soon became my problem; within a couple of months I saw myself taking support calls and fixing bugs by working over 18 hours a day; hating the code I had written in a hurry and fixing it where possible. It could have bitten me really bad, but thank god it didn’t. We fixed all major issues that were reported and No-one was killed. There was nothing about that project I enjoyed in particular, but it taught me to strike a balance. It taught me to ship at Point M because M is an idle point to ship.
Shipping at point M in the above graph, involves it's own set of challenges though. It means maintaining constant communication with the Stake-holders, reporting accurate status, remaining agile and selling the idea that Quality would mean lesser cost in the long run to the Stake-holders even at the time when pressure to ship is constantly increasing.
What does this boil down to? While the book suggests some excellent code-related-techniques of how Fred can become a programmer who does not program by coincidence, in my opinion however, It also boils down the fact that to ship at M Fred needs to learn a whole host of other skills which have nothing to do with coding. Skills which Fred always considered unimportant as a developer. A mentor remarks - "Software development is not all about For loops. A lot of software development is about Managing Risks and so many other things". These are In fact, words of wisdom which deserve a different post for themselves.