"The Pragmatic Programmer"

April 26th, 2019

I’m currently reading "The Pragmatic Programmer" by Andrew Hunt and David Thomas. The book includes patterns and approaches to problems used by productive programmers. This book reads as if someone sat by seasoned programmers to collect years worth of solid advice and turn it into a book. In this post I’m going to share my main takeaways for the first couple of chapters.

Chapter 1 - A Pragmatic Philosophy

The first chapter discusses a pragmatic philosophy, which they describe as an attitude towards programming. A pragmatic programmer will think beyond the immediate problem and consider the bigger picture; view programming as a craft; and take ownership for the quality and maintenance of the work that they produce. The advice that resonated with me the most included:

"Make quality a requirements issue — the scope and quality of the system you produce should be specified as part of that system’s requirements.”

When you’re writing software, you define features or products that will meet your client’s needs. Even if the code is perfect, and your features are fantastic, you can’t say that you have quality code if they don’t meet the needs of your clients. In order to meet those needs, there should be a feedback loop and a process to gauge the users’ satisfaction. Getting feedback early and often will lead to a better solution.

"Invest regularly in your knowledge portfolio — The process of learning will expand your thinking, opening you to new possibilities and new ways of doing things.”

Hunt and Thomas liken investing in your knowledge portfolio to managing a financial portfolio: invest regularly, diversity your knowledge, balance your knowledge between conservative and high risk areas, invest in knowledge before it becomes popular, and review/rebalance your investments. I love learning about new technologies through different resources. I read books, talk to people at work, go to meetups and workshops, and find different ways to learn new languages. One tip that I would add is to teach others. Topics become even clearer after you challenge yourself to make it easier for someone else to pick up. Just having to take those steps to bring someone up to speed on a technology helps you solidify your knowledge and exchange ideas for further areas of growth.

“Critically analyze what you read and hear — You need to ensure that the knowledge in your portfolio is accurate and unswayed by either vendor or media hype.”

It’s important to think critically about the technologies or solutions that some people swear by. Neglecting to take time for critical analysis can be costly and a headache for your team. Related to this is the importance of having a trusted network of software gurus and continuously asking questions. This pattern made me think about the latest cryptocurrency and blockchain (and any other buzzwords) trend. Having an extensive knowledge portfolio and network will help you distinguish between commercial trends and actual solutions.

Chapter 2 - A Pragmatic Approach

The next chapter talks about an approach to software development that considers the ever evolving pace of technology and client requirements, and provides techniques to protect projects within its changing environment. After defining several types of duplication and ways to approach them, Hunt and Thomas go on to define a “critical concept if you want to produce systems that are easy to design, build, test, and extend.” The concept is Orthogonality. It looks like an involved term, but it simply boils down to independence. “Two or more things are orthogonal if changes in one do not affect any of the others."

“Eliminate effects between unrelated things — we want to design components that are self-contained: independent and with a single, well-defined purpose”

When projects are built in this fashion, they are easier to test and to extend; the project is less fragile since problem areas will be isolated and therefore easier to change; and they are easier for teams to work with since components have well-defined responsibilities. A couple of my main goals throughout my apprenticeship include learning how to design systems so that they can easily respond to change and learning how to keep my code decoupled.

“Use tracer bullets to find the target — tracer code is lean but complete, and forms part of the skeleton of the final system.”

Hunt and Thomas describe tracer code as code that is not fully functional but has an end-to-end connection among components. It’s particularly useful when you don’t know where the project is going or you’re unsure how to meet the target. Start with a basic structure and gradually add new functionality until you meet your goal. For my last project, I coded modules in a vacuum. I didn’t build an overall system first and I didn’t integrate the modules until the very last moment. However for my current project, I built a walking skeleton. I set up a repository, added test suites with a passing test, set up the client and server with one HTTP method, and then deployed it to Heroku. There was nothing but a title on the page, but adding functionality and integrating new pages was simple. I think this technique lays out the foundation for producing code in vertical slices (where each iteration hits the frontend, backend, and database).

“Iterate the schedule with the code — you’ll have to help [management] understand that the team, their productivity, and their environment will determine the schedule"

Estimation is one of my pride injuring weaknesses at the moment. It’s been easier to code after defining user stories and place them on my calendar, but I still find myself overloading my week. I always feel that I can do certain things within a certain time period; I consistently underestimate the complexity of new features or refactors. One estimation trick that Hunt and Thomas prescribes is simply asking someone who’s already solved the same problem. Try to see how they solved the problem and draw from their experience. Hunt and Thomas continue with an estimation exercise which includes understanding the scope of the domain; building a bare-bones model of how the system might be implemented; decomposing the model into components; assigning values to each parameter that contributes to the overall model; and defining critical parameters to help calculate solutions. It was nice reading about this exercise, but the number one take away for me from this section was what to say when asked for an estimate, which is “I’ll get back to you.” I struggle with this because I always feel pressured to produce or have an answer as soon as I get a request or question. However, I’m starting to use this phrase more often to better set expectations and maintain good relations with those around me. This phrase allows you to take time to really think about the problem and break it down step by step.

I'm looking forward to the next chapters of the book which deal with technical tools and implementations. As I continue through my apprenticeship, it’s interesting to see how the approaches that I’m learning from different gurus all complement one another or describe the theory behind the technical approach. I’m trying to remind myself that these tools will not be developed overnight but will come with experience.