The Pragmatic Programmer 20th Anniversary Edition
The first edition of this book was released in 1999 and has become one of the most important books to read for software developers.
Last year, 20 years after its initial release, the authors released a new edition of this book, not only including updates of the code examples, but also integrating the feedback they gathered at this time.
While the book contains code samples, it's not about teaching you how to code: The authors explain how to improve the process of developing software in a pragmatic way. It includes plenty of tips that will help you throughout your programming career.
Some of the traits of pragmatic programmers are their attitude and philosophy of approaching problems, placing them in its larger context, and taking responsibility for everything that they do.
I've only read the book 3 years into my career as a software developer, but I'm sure that I will be able to appreciate the book, even more, when I read it again in a year or so.
I'd recommend it to all software developers who are serious about improving their skills. However, while it contains a lot of useful advice, I feel like if you're just starting out with programming, you might not come to appreciate all the wisdom that the book offers.
If you want to buy the book, you can get it here on Amazon (affiliate link).
Favorite topics
The Pragmatic Programmer has a total of 53 topics. As with any non-fiction book, some ideas resonate with the reader and others don't.
I want to share a short summary of each of my favorite topics here and how I integrated them into my work. These are the topics that I liked the most after reading the book for the first time, but I'm sure that if I read the book again a few years from now, my takeaways will be different.
It's your life
This topic is at the very beginning of the book and has a motivational vibe to it. Many developers that Dave and Andi have talked to are frustrated with their jobs or the technology they're working with.
The authors highlight the fact that software development is one of the best careers to have nowadays since developers usually are well paid, can work from anywhere in the world, and have a lot of freedom in their jobs.
If you're not happy with the job you're working right now, you can try to fix it by talking to your boss or find yourself another job easily.
Given how privileged software developers are, there's no excuse for not living the life you want. If you're proactive and stay on top of your game, you'll be rewarded with a lot of opportunities by the industry.
Knowledge portfolio
The knowledge portfolio of every developer is like a regular investment portfolio: If you invest in it regularly, you will reap the benefits of that later on.
I found this analogy to be the most powerful in this book since I read it at a time where I wasn't developing my programming skills any further and I felt like I was hitting a glass ceiling. I wasn't investing in my knowledge portfolio and I came to a point where I noticed the results of that.
Regularly investing in yourself by reading non-fiction books will help you stay curious and motivated about your profession (they don't have to be all programming related).
It also helps to discover more things that you don't know, making Unknown Unknowns, Known Unknowns. This idea is not from the book, but I think it is related.
The more you learn about a certain topic, the more you see the complexity in it and the more you see the little you know about it. You can read more about this in this Medium post.
The authors suggest you invest in your portfolio by doing the following things:
- Learn at least one new language every year
- Read a technical book each month
- Read nontechnical books, too
- Take classes
- Participate in local user groups and meetups
- Stay current (by reading news and posts online)
You don't have to do all of them, but consistently developing yourself with these suggestions will definitely help you expand your portfolio.
To get notified about articles like this one, subscribe to my email newsletter.
Orthogonality
This is a term borrowed from geometry. We probably know this concept under names like modularity or layered systems. In the end, all of them refer to a system whose components are loosely coupled, meaning that the components don't have a lot of dependencies.
In orthogonal systems, it's easy to change one component without the fear of breaking something on the other end. These systems are also easier to test.
Thinking about orthogonality during the development or design stage of a system can help a lot in making the system easier to work with in the future and prevent bugs.
Tracer bullets
In the shooting scenes of any action movie, you can often see the path of the bullets. Bullets that mark the path they've taken are called tracer bullets.
Tracer bullets are used in real-world combat as well because they help to aim under difficult environments by providing immediate feedback under real circumstances. They are not supposed to hit the target right away, but the fast feedback allows the gunner to adjust the aim.
The equivalent in software development is to get a small part of the system working as soon as possible and asking for feedback from users and stakeholders.
Advantages of the tracer bullet approach are:
Early and visible results for your users and sponsors.
Developers have a structure to build upon.
The project becomes an integration platform:
New changes are integrated into an already working system.
The alternative to the "tracer bullet approach" would be writing each module of the system separately, connecting them in the end together, and test the whole system at the very end of the project.
Tracer bullets aren't meant to be prototypes. They're meant to get a stable version of a feature or aspect of the final system that will be the backbone for future developments.
Just like with the bullets, you won't always hit the target at your first shot. Users or stakeholders might not like the result, but the whole idea of this is to get this feedback at the beginning of the project rather than at the end.
The basic tools
This chapter of the book contains an overview of the tools that every programmer should use. The authors compare programming tools to the tools of a woodworker, which also inspired the cover of the book.
Woodworkers use a variety of tools, each of them having its specific purpose. They use tools like rules, drills, clamps, and many more. The woodworker knows when to use which tools and has mastered how to use it.
In programming, we have our own tools that we need to get the job done. These tools amplify our talent by increasing productivity.
In the book, they advise against the usage of a single power tool, an IDE, and encourage you to use the tools that an IDE uses behind the scenes.
The tools covered in the book fall into the following categories:
- The power of plain text
- Shell games (Unix commands)
- Version control
- Power Editing (Your text editor)
- Debugging
- Engineering daybooks
Don't rely on GUI environments
Unix commands are so powerful because each of them has one single purpose and they can be combined through pipes, which opens up an infinite amount of possibilities to what you can do with them. It's to the programmer what the workbench is to the woodworker.
Using the shell allows you to automate things and combine commands in such a flexible way that GUIs can't keep up with.
Dead programs tell no lies
A dead program normally does a lot less damage than a crippled one.
The tip of the authors for this topic is to crash early.
Why? Because if you don't, your program will maybe look like it's working correctly but returns slightly wrong results due to the system being in a wrong state.
You can avoid this by crashing early and often. This will help you to find the root of the bug faster and it will be more apparent when something is wrong with the program.
Wrapping your code in try catch
statements might keep the program running, but the subtle bugs that are the result of that are much harder to catch.
Data validation in Mobx-State-Tree
This is one of the aspects I like about Mobx-State-Tree, a frontend state management tool. It crashes early by validating the data before adding it to the store that contains all the data on the fronted.
At first, this seemed annoying to me, since the app crashed as soon as the backend returned the wrong data. After giving it a second thought, this approach is much better than keeping the program running.
The alternative would be that, after receiving an unexpected null value, for example, the app crashes anyway because I'm trying to read a property from
undefined
(JavaScript equivalent to a NullPointerException).Having worked with it for nearly 2 years now, I can say that with this helped me on multiple occasions to track down bugs faster than it would've taken me without validating the data.
Programming by coincidence
Don't assume it, prove it.
Programming by coincidence means that you're making guesses about the functions and interfaces that you're using. It might work for a while, but since you don't know what you're working with, bugs can show up, which will be difficult to track down later on.
The result is that, whether your code is working or not, you don't know why.
As a remedy to programming by coincidence, you shouldn't guess what's the purpose of a given interface but read the documentation. If you can't rely on the documentation, or there isn't one to begin with, document (and test) your assumptions.
I found the advice of this topic to be helpful when working on projects with a messy codebase where functions would have unexpected side effects.
Test to code
Testing is not about finding bugs.
This topic is all about testing and why we test our code in the first place. Especially unit tests help us think about our code in a more goal-oriented and decoupled way.
One of the authors (Dave) stopped writing tests for a while to see what impact it would have on his code. To his surprise, the quality of his code doesn't suffer at all.
That doesn't mean though that you should stop writing tests as well. He's been programming for over 45 years now, and he automatically writes code in a decoupled, testable way.
I already wrote an article on unit testing react, where I go more into depth about the purpose of unit testing.
Pragmatic starter kit
This topic is more of a recap of the topics covered in the book. It covers the most important things that you need for any software project, which are:
- Version control
- Regression testing
- Unit testing
- Integration testing
- Performance testing
- Property-based testing
- Full automation
Conclusion
That's it, these are the main takeaways for me from the book. There are many other important topics that I haven't listed here. If you've read the book and have other topics that are your favorites, feel free to let me know in the comment section.
I believe it's one of the books that every developer should have on their bookshelves. If you don't have it already, you can get it on Amazon (affiliate link).
Further reading
- Unit testing React - What you need to know
- High Performance Mobile Web by Maximiliano Firtman - Book review and notes
As an amazon associate I earn from qualifying purchases. This means I receive a small commission if you make a purchase when clicking on any amazon affiliate link at no additional cost to you.