Over the course of reading this book, I kept coming back to two thoughts.
Firstly, I think Farley undersells the advances that programming languages have made. He has a point that the level of bikeshedding about languages that programmers are capable of is too much, but treating it as completely nothing is throwing the baby out with the bathwater. Take an example close to my heart: comparing Objective-C and Swift, there have been some significant advances. The introduction, and use throughout the language and libraries, of optionals has functionally eliminated null-pointer exceptions. Memory management bugs are a massive category of problems, across all sorts of software. Look at Heartbleed, for example. If you’re using Swift idiomatically, and avoiding the (hilariously named) UnsafePointer
stuff, this sort of problem cannot happen.1
Secondly, this book felt like the moment where in my mind I went “oh, we are getting there.” He makes a point early on that software engineering as a field has different standards of success than other engineering disciplines. Again, an example: this morning, I woke up to a truly terrible software bug in an app I use that had deleted several years worth of data. This is a bad bug, and I’m personally quite upset about that loss, but it’s not as bad as, say, the Tacoma Narrows bridge collapse. Subjectively, it feels like software as a whole has a lower bar for “is this okay to produce” than the other, physical engineering disciplines.
Where this book changed my opinion is in starting to feel like the field is beginning to coalesce around some standards. We’re nowhere near the level of “you have to use these techniques, and if you don’t you can lose your Software Engineering License and be prohibited from working professionally in the field,” but some of those techniques are taking shape.2 Farley’s argument is that the core of it is fast feedback, allowing for tight iteration loops, and from that it logically follows that test-driven development is the best option.
And yes, I’m sold! Just the other day, while doing some tinkering on a personal project, I found several bugs I’d created — because the tests I wrote before I started writing the code failed. That’s such a nice way to do things. And now, having written both the code and the tests, I feel much more comfortable with the idea of “oh, I’m going to need to reuse some of this logic somewhere else, I’ll just pull it out into a separate chunk.” I don’t have to spend an hour thinking through “what might break from this,” or testing things out. I just do it, run the tests, and know that I’m good.
As to the book itself: he’s hammering the same points over and over, as these sorts of books tend to do. I found it a generally good read, and took many notes for the book club discussion, but I don’t know that it was particularly world-changing… or if anyone else will have the same “eureka” feeling from it that I did. That moment came with a very clear sense of “all the other stuff I’ve read and done leading up to now came together into this idea.” It’s not a bad book, though, and could be a pretty good starting point if you’re just getting into the “read about the field” kind of thing, so check it out.3
- And I’m also setting aside the type checker, which is, for all intents and purposes, a form of mandatory unit testing imposed at compile time. Writing Swift, you don’t have to safety-check your inputs to make sure they’re the right types; the language does it for you. ↩
- I do absolutely believe that software engineers should be forming some kind of industry group and establishing shared standards for what “software engineering” actually means. ↩
- This is a Bookshop affiliate link – if you buy it from here, I get a little bit of commission. It won’t hurt my feelings if you buy it elsewhere; honestly, I’d rather you check it out from your local library, or go to a local book store. I use Bookshop affiliate links instead of Amazon because they distribute a significant chunk of their profits to small, local book stores. ↩