Highlights from "The Pragmatic Programmer"

By David Thomas and Andrew Hunt

Cover of the book The Pragmatic Programmer

There’s one technique that you must use if you want people to listen to you: listen to them.

Unless you work in a vacuum, you need to be able to communicate. The more effective that communication, the more influential you become.

A thing is well designed if it adapts to the people who use it. For code, that means it must adapt by changing. So we believe in the ETC principle: Easier to Change. ETC. That’s it.

You may need to spend a week or so deliberately asking yourself “did the thing I just did make the overall system easier or harder to change?” Do it when you save a file. Do it when you write a test. Do it when you fix a bug.

Our experience is that it requires some initial conscious reinforcement.

DRY is about the duplication of knowledge, of intent. It’s about expressing the same thing in two different places, possibly in two totally different ways.

when some single facet of the code has to change, do you find yourself making that change in multiple places, and in multiple different formats? Do you have to change code and documentation, or a database schema and a structure that holds it, or…? If so, your code isn’t DRY.

The code is the same, but the knowledge they represent is different. The two functions validate two separate things that just happen to have the same rules. That’s a coincidence, not a duplication.

We feel that the best way to deal with this is to encourage active and frequent communication between developers.

And make a point of reading other people’s source code and documentation, either informally or during code reviews. You’re not snooping—you’re learning from them.

if you fail to reuse, you risk duplicating knowledge.

Two or more things are orthogonal if changes in one do not affect any of the others. In a well-designed system, the database code will be orthogonal to the user interface: you can change the interface without affecting the database, and swap databases without changing the interface.

If I dramatically change the requirements behind a particular function, how many modules are affected? In an orthogonal system, the answer should be “one.’’

Write shy code—modules that don’t reveal anything unnecessary to other modules and that don’t rely on other modules’ implementations.

But if you really abstracted the idea of a database out—to the point where it simply provides persistence as a service—then you have the flexibility to change horses in midstream.

What you can do is make it easy to change. Hide third-party APIs behind your own abstraction layers.

Tracer code is not disposable: you write it for keeps. It contains all the error checking, structuring, documentation, and self-checking that any piece of production code has. It simply is not fully functional.

Computer languages influence how you think about a problem, and how you think about communicating.

These highlights are sourced from my Kindle using Readwise. Readwise automatically syncs all your highlights from various sources. It's cool. Referral link if you'd like to try.

Get letters from me 🙌

Get a behind-the-scenes look on the stuff I build, articles I write and podcast episodes which make you a more effective builder.

Read the archive 📬

One email every Tuesday. No more. Maybe less.