Books

Book Cover
History Politics Book Club
Finished: July 2025

To Start a War

by Robert Draper

I didn't really know much about Iraq or the Bush administration before reading this, and now I do.

I think the main takeaway from the book is that the administration's entrance into Iraq was more a result of bureaucratic incompetence than it was about oil.

Draper does a good job of humanizing key figures in the administration, to the point that you can really appreciate (for example) Colin Powell's mindset before giving his UN speech, and even the mindset of George Tenet leading up to said speech.

To grossly simplify, the war was largely due to Bush's inability to hear two sides of a conversation, and his insistence that his direct reports come to an agreement, rather than mediating such debates himself. The fact that Wolfowitz and Rumsfeld were unmoving in their convictions that Iraq posed a threat to the United States was, as a result of Bush's inability to hear two sides of an argument, sufficient to force their opposition to gradually side with them over a period of a few years.

Book Cover
History Book Club
Finished: September 2025

The White Nile

by Alan Moorehead

Half engaging journey of exploration, half easy-to-see-coming exploitation and aftermath.

From the outset this book seems to be kind of a summary of the explorations done by Livingstone and his peers in the 1800s. The explorers are detailed very well; their personal lives, habits, etc. are recorded pretty well in the books that they wrote about their travels, although Moorehead provides some more modern criticsm of their actions and behavior.

In the second half or so of the book, however, things take a sharp turn, and the explorers we've come to know so much about give way to war and death. The character of the Madhi is left somewhat to the reader's imagination as a larger-than-life figure. The battles over Khartoum and the fate of the city and its inhabitants are a little drawn out - the result is obvious to a reader paying attention, and Moorehead hints at the end result many times throughout the book - but it's still devastating nonetheless.

Book Cover
Politics Book Club
Finished: October 2025

The Fort Bragg Cartel

by Seth Harp

Eye-opening case study and description of what went on at home and overseas during and as a result of the latter days of America's Afghanistan era in its forever-war.

This book made me happy that I'm not in a situation where I need to be part of the military. It also somehow managed to paint the Taliban in a good light, at least in comparison to the insane compromises made by US leadership in their alliance with the Northern Alliance, including crimes against children (look up bacha bazi if you are unconvinced) and the facilitation of the opioid epidemic.

Book Cover
Sci-Fi Book Club
Finished: March 2026

Brave New World

by Aldous Huxley

Kind of a mirror image of 1984, maybe combined with Gattaca.

I liked this book, but towards the end the worldbuilding kind of fell apart and I found myself nitpicking inconsistencies.

(Spoiler alert) Around the end of the book, one of the "World Controllers" is describing to the main characters why the world needed to turn to genetic engineering and a caste system. He describes the following scenarios that they tried or considered: (1) the scenario where they automate everything, and they have no more need for physical labor, and (2) the scenario where they stop genetically sabotaging people so that they become mentally deficient (e.g., Epsilons and Deltas) and instead only have people that they genetically modified to be intellectually superior (i.e., Alphas).

He states that the first scenario wouldn't work because they need to have something for the Epsilons and Deltas to do, otherwise they would just be a net drain on society and become disruptive. He also states that the second scenario wouldn't work, because then the Alphas would get into arguments about who needs to do the menial factory work that is beneath them.

This false dichotomy is destroyed when you consider the case where they both automate everything and also only create Alphas. There is basically no downside, and this situation prevents both issues from the above scenarios.

The other issue I had with the given scenario is that they felt they needed to go so far to prevent unhappiness that they needed to hypnotically condition people against monogamy. Obviously if people do not want to practice monogamy that is up to them; but monogamy is kind of a state of nature for most humans, and to deny that with social and hypnotic conditioning is not a great solution. In general, the prevention of unhappiness (as it's phrased in the book) is taken past the point of diminishing marginal utility. They already cured all known diseases, and are able to ensure that everyone can be an "Alpha", physically and intellectually fit. With that alone, a good deal of unhappiness is wiped out. But once you get to dictating people's love lives, you go past the point of diminishing marginal utility and start making things worse. In the book, for example, one of the main characters (Bernard Marx) is actually made unhappy by the anti-monogamy situation, so there is a clear counterexample available for the so-called World Controllers to see.

So in general, the book was a quick and engaging read, but the sci-fi scenario left something to be desired.

Book Cover
Project Management Software Engineering Book Club
Finished: April 2026

The Mythical Man-Month

by Fred Brooks

Ahead of its time in many ways, with some notable misses.

The book covers a lot so I'll address each chapter's thesis (each chapter is a separate essay) and describe whether it holds up today, based on my experience, and my thoughts on it (if any). Obviously with the widespread use of large language models things may have changed significantly in this area, but how much things have changed is still up to debate.

    Chapter 1: The Tar Pit: This chapter essentially says that software engineering will always take more time than you think, because it is a complex process that balances the design, integration, and testing of components with the productionizing of a system.

    My thoughts: This is a pretty general point that holds up not just in software engineering but probably in many fields (not that I am really familiar with fields besides software). I would argue that not all software needs to be productionized. Certainly lots of software that I have worked on is never really productionized but rather, in the words of Macduff, "from [its] mother's womb / Untimely ripped", and in the words of Richard III, "Deformed, unfinished, sent before [its] time / Into this breathing world scarce half made up". In less Shakespearean terms, a lot of the software I have written and have seen in the wild is thrown together quickly and patched up later as needed. For the purposes that Brooks is describing in his book, however, that's less acceptable, given he is describing the software building process for an operating system rather than yet another internal-facing reconciliation report without any real audit impact.

    Chapter 2: The Mythical Man Month: This chapter discusses how men and months are not interchangeable, or rather that they can be but that the mapping is not linear but something closer to polynomial or exponential.

    My thoughts: I haven't worked on a project of the scale Brooks describes from start to finish, so I haven't really been able to see whether this works in practice. These days I think software tends to be built more fluidly with sprint cycles rather than large deliverables; at least, that's how it works for internal-facing software. Even for external-facing software, like apps on an app store, sprint cycles can be used because the Internet exists now and features and fixes can just be pushed to people's devices automatically. This means that the timeline of a software project is much more flexible, and the "deadline pushback" of adding people to a project takes the form more of a vague intermittent performance degradation in software update cadence as newcomers are brought up to speed than anything else.

    I do agree with Brooks on his point about bringing people up to speed though. Without documentation or at least well-commented code it tends to be a little more difficult. It's necessary for people with experience working on the project to take time out of their day to do at least a brief knowledge transfer for the parts of the project the newcomers will be working on. But again, given the more drawn-out "indefinite-maintenance-mode" software development timelines, newcomers have all the time in the world to slowly learn the ropes by being assigned tickets that begin small and increase in scope over time as they get used to the project.

    Chapter 3: The Surgical Team: This chapter essentially says that one person should have the entire responsibility for a component's architecture, and that there should be a number of others around him that act as designated assistants.

    My thoughts: I don't think this holds up too well today. Rather than having only one person own the architecture/design of a component, it's better to have at least two owners so that there's coverage in case new features need to be added while one is on vacation or otherwise unavailable, to prevent a bus factor of 1. Additionally, some of the roles are obviously obsolete now, like the (two!) secretaries, the editor, and the clerk. Most of the remaining roles are replaced by organization-level teams, like a devops team, and the budget management done by the administrator is also done at a higher level by the team of a COO reporting to a the CTO or something similar.

    The roles of language lawyer and toolsmith are pretty much obsolete as well, because the tooling for modern programming languages is very polished and uniform (IDEs with LSP support, autoformatting and smarter tools are pretty ubiquitous now). LLMs help with this too.

    Chapter 4: Aristocracy, Democracy, and System Design: This chapter argues that the ratio of function to conceptual complexity should be as high as possible - specifically that having too many functions in a piece of software, to the point that it significantly increases its conceptual complexity, is bad.

    My thoughts: I think that this is reasonable when discussing a single component of a piece of software, but when software has many separate components, I think it doesn't make sense to look at them in aggregate and construe that their abundance of functionality is bad. Rather, the "ratio test" should be used to determine when it's time to refactor a large component into separate sub-components, or on a smaller scale, split a large module into sub-modules or a large file into separate files.

    Chapter 5: The Second System Effect: This chapter says that often, the second system designed after the initial successful system is often too full of features and loses the conceptual integrity and/or simplicity of the initial system (it is over-designed).

    My thoughts: I think this chapter is less relevant now, because we very rarely do a full redesign of a piece of software and make a real "second version". I actually think that lots of these chapters are more relevant to fields like game design than modern software development, because of the conceptual separation between different versions of a game when compared to, say, the degree of conceptual separation between 2025's version of iOS and 2026's version of iOS. It's a common thing to see that indie games produced after an initial success can succumb to feature bloat and extended timelines (e.g., Hollow Knight: Silksong, Deltarune). Some games also finally reach a version that people really like, but never manage to move on,like Skyrim and GTA V. These games probably share the same motivations for feature bloat with those of Brooks' pieces of software - a new version always has to outdo the previous one, and the success of the previous version lends itself to a large budget to make these new (possibly questionable) features that would otherwise not be implemented. It's probably on video game design teams where the techniques described in this chapter to nudge software designers away from feature bloat are the most relevant (as seen in Hollow Knight: Silksong's development process, where the publishing agent had to kind of fill this role).

    Chapter 6: Passing the Word: This chapter describes the need for both a formal description of how a system works, and a prose description for comprehensibility.

    My thoughts: I don't think this one holds up too well today. Documentation is certainly useful, especially for large projects where there is lots of code reuse, mostly in the case of common libraries. But formal descriptions of how systems work don't really appear anymore (outside of the formal programming language specification sphere), and are not as relevant unless you're writing papers on some new cryptography system or blockchain idea.

    Chapter 7: Why Did the Tower of Babel Fall? This chapter discusses how communication and organization is required for software projects. It also states that the entire software system should be transparent to all developers, although Brooks says in his "Propositions of The Mythical Man-Month: True or False?" chapter that he has been convinced otherwise, and that software components should have their inner workings opaque to external users.

    My thoughts: The idea of component opacity (the OOP term is encapsulation) is now widely practiced in all languages, not just in OOP-centric ones. Even non-OOP languages like C will expose function definitions and expect users to take them at face value.

    The communication and organization message of the chapter is important too; there is some overlap in the organization part with the previous chapter on documenting the system, but the bit about teams needing to communicate changes to each other is definitely relevant. Software teams should have an idea of the upstream and downstream dependency chain that their changes will impact, and ensure that they inform those dependency owners well in advance of any API (or database) changes so that the dependent teams can make the relevant changes on their end so things work.

    Chapter 8: Calling the Shot: This chapter says that as the scope of a programming task increases, overhead increases at a rate higher than linearly. It also says that using a high-level language can decrease this overhead significantly, and that productivity gains are around 5x.

    My thoughts: There's definitely more overhead as the size of a project increases, because you need to account for more moving parts and more dependencies even within your own project (let alone the upstream and downstream dependency issues described above).

    Also, I've been using high-level (by Brooks' standards, C and above are "high-level", but I've been using mostly Python which is worlds above C in whatever level hierarchy one wants to make up) programming languages for my entire programming career. You don't need to look at the TIOBE programming language index or the Stack Overflow developer survey to know that the so-called low-level programming languages are really not used at all anymore. Brooks was clearly right about this one.

    Chapter 9: Ten Pounds in a Five-Pound Sack: This chapter discusses keeping program size small so that it can fit into memory.

    My thoughts: This chapter is completely obsolete because memory sizes are now colossal compared to program sizes.

    Chapter 10: The Documentary Hypothesis: This chapter says that a small number of documents end up being used to make most of the decisions by project managers.

    My thoughts: I think this chapter is a bit vague. I think that in many cases, the documents needed for high-level meetings are created just-in-time by the people who have worked on the system, and provided to project managers on request. This makes the documents less relevant outside of their designated meeting context but makes them immensely more accurate at their time of use. I think this method is better, provided the software engineers are sufficiently competent in document-creating or diagram-creating software to be able to generate these documents quickly and effectively.

    Chapter 11: Plan to Throw One Away: This chapter advocates for the use of a beta version for software, which gets discarded or heavily refactored before any version is shown to real users. It also describes how software maintenance can take around 40% of the total time and/or resources invested in the initial software development, and advises towards building systems that are easily repairable.

    My thoughts: With regard to the beta version item: as with many of the other chapters, this is a good idea for "one-and-done" pieces of software like games, where the initial release is the most important time for the software, so that it can gain adoption. For internal software and tools, however, I would argue that the initial release of the software is a beta version, or at least serves that role, without requiring a full rewrite, since adoption within an organization is necessarily slow until the technology has reached some minimal level of maturity. In other words, I don't think this is as relevant in the context of my experience and current role.

    For the software maintenance part: this is definitely relevant to my experience, although I might go further to argue that software maintenance is more than two thirds of the total software development cost (rather than just some percent of the initial development cost). Building systems that are repairable is a great idea, even if it costs you some amount of job security (the next guy will thank you).

    Chapter 12: Sharp Tools: This chapter emphasizes the importance of good tools for software engineering, including dedicated machines for debugging, and a performance simulator.

    My thoughts: I don't think this one held up too well in the examples it described, since debugging is always done on one's own machine and performance is much less of a concern for people now (not that it shouldn't be more of a concern, but that's how things have shaken out). But the general emphasis on good tooling has definitely held up. If your tools are constantly breaking when you're trying to work with them, it destroys your flow state and the impact to your sprint timeline can reduce your credibility (and/or that of your team) with end users.

    Chapter 13: The Whole and the Parts: This chapter advocates top-down design and structured programming as techniques to make designing complex systems easier.

    My thoughts: Both of these have become commonplace today, structured programming especially (all programming languages support this method, maybe aside from esoteric ones like Forth). The chapter cites Niklaus Wirth (creator of Pascal) who was definitely ahead of his time as well; I didn't know that he came up with the top-down approach idea too, I actually attributed structure programming to him more than Djikstra (although Brooks cites Djikstra for this).

    Chapter 14: Hatching a Catastrophe: This chapter states that large project delays are caused by a series of small project delays which in themselves may seem negligible but combine to create significant issues. It recommends making milestones that are "so sharp [read: concrete] that [the programmer] can't deceive himself;" and ensuring that if you miss one deadline, you make the next one, to avoid a decrease in morale.

    My thoughts: The statement about how small project delays combine to create larger ones is a fact of life. I think the ways Brooks approaches solving that issue are similar to the way "SMART" goals work: Specific, Measurable, Achievable, Relevant, and Time-bound. Having individual contributors make these Specific goals themselves forces the milestones to be "sharp", and to ensure milestones aren't missed, you can tie these goals to manager feedback so that meeting them has an impact on employee compensation. This has two wonderful effects: (1) you put the onus on the employee to meet the goals in time rather than being forced to help them achieve the goals on your own, and (2) it's a great excuse to dock their bonus if they don't meet the goals they gave! (Obviously I'm being facetious, I hate the method of making employees set SMART goals for themselves for exactly these reasons, even if they are effective from a managerial standpoint.)

    Chapter 15: The Other Face: This chapter describes how programs are typically interacted with in ways that are not anticipated by testers, and therefore the number of bugs found by users increases rather than decreases as adoption of the software package increases, eventually tapering off or decreasing again. It says also that programs should be self-documenting, and that programmers should make sure to write documentation (and we should teach programmers to do so as part of their educations).

    My thoughts: The first point is basically just this meme, which is of course accurate. The next point is good, although depending on how good the software developer team is, you may find that the rate at which bugs are found never really tapers off. The point on documentation is of course classic, you can't really get away with using single-character variable names in your code unless they're really obvious, like for s in scenarios or something similar, without having anyone who reads your code admonish you for doing so. LLMs can be good at fixing these issues.

    Chapter 16: No Silver Bullet - Essence and Accident in Software Engineering: This essay argues that "there is no single development, in either technology or management technique, which by itself promises even one order-of-magnitude improvement within a decade in productivity, in reliability, in simplicity."

    My thoughts: The elephant in the room on this one is LLMs. There are lots of people who probably claim that they can get (at least) one order of magnitude of productivity improvement from the use of LLMs. And for one-shot tasks, where code quality is less important than just completing the task, or for localized refactoring work, or for a single-component change, they could be right - a sufficiently good LLM could make the change in a couple of minutes with no additional work needed from the prompter. But in aggregate, across large codebases with significant complexity, I think Brooks' statement holds up today. At least, until the next generation of LLMs rolls around, or we get some AGI-adjacent agentic editing capabilities made widely available. For now though, it seems like the bubble will burst long before that happens.