I just finished it and haven't sat down to write a proper review yet.
But I thought it was very uneven in value.
The parts about deep and shallow modules, what good interfaces are, _why_ keeping everything about their implementation hidden is so important -- those were very good.
He also advocated against having small routines, which are almost dogma nowadays (mostly because they're easier to unit test), and he's pretty convincing. That would mean that "making your code easier to test also improves its design" is wrong.
Other parts about documentation etc I thought were too long and not very interesting. Then the bit at the end about optimizing for execution speed was very interesting again, though perhaps because I had never read much on the subject, before, I don't know.
> That would mean that "making your code easier to test also improves its design" is wrong.
I assume that quote is talking about unit tests, but it's becoming more and more accepted that integration tests are more important than unit tests. https://kentcdodds.com/blog/write-tests
This shift away from unit tests is the corollary to Ousterhout's preference for deep modules.
In my experience, honestly the advantages of a unit testing suite are extremely minimal depending on your integration test runtime.
However, they're a good tool if for example you're working with a Big Data system, where an end to end integration test will necessarily take an extraordinary amount of time.
For my first job out of school in Apache Spark they were absolutely brilliant. For my current codebase? Not so much.
However, TDD just reduces the number of mistakes I make by an umpteenth amount.
Just because it breaks my code up into extremely short subroutines so I screw up less. Plus writing the unit test itself is a brilliant way to "measure twice, cut once."
I disagree that most tests should be integration tests. He seems to dismiss them in the article because of his experience with diminishing returns with test coverage and tests that test implementation details which basically means the tests aren’t made correctly and/or targeted at the right areas. He also seems to dismiss the pyramid rather quickly without giving a good reason against it (unit tests are quicker to run and cheaper to implement). This is not to say we should ignore integration tests entirely (or e2e tests for that matter), just that a shift to the traditional guidance is still valid.
It wasn't a direct quote, but an idea I've heard repeated many times.
And integration tests are nice, but the idea of testing small units was that every branch in the code under test doubles the number of possible execution paths, so tmit becomes harder and harder to test every path.
So we should branch less, I guess. His parts about "define errors put of existence" and writing more general code with fewer obscure details would probably help.
Although its ideas are heavily couched in OO terminology, it's changed my ideas about interfaces and exposure to complexity utterly.
Not comprehensive, but every programmer should absolutely read it (it's a tiny book after all).