2022 in Books

Business

Initially this book was not on my reading list, but my manager encouraged me to read it so I moved it to the top of the queue1. The book covers the experiences of 2 Navy SEALs, the authors of the book, in the Iraq War and in their later life as leadership consultants. Each chapter begins with a combat story that transitions into a single principle. Then the authors apply that principle in an anecdote from their consulting work. The format and laconic style are effective at transmitting their message, even if sometimes the stories may not match the principle. For example, the last chapter “Discipline Equals Freedom” begins with a story about how a new search procedure replaced their old ransack method but ends with a story about a CEO who needed to fire his friend.

Much of the book can be reduced to “find a way”. Take ownership of your failures; use your agency to affect your surroundings. This is great advice for individuals but not for organizations or countries. Despite the successes Jocko Willink and Leif Babin and the rest of Task Force Bruiser fought and bled for during the Battle of Ramadi, the Iraq War was a failure. The decision to overthrow a dictatorial regime and establish a new democracy created a insurgency, the rise of ISIS, and a stronger Iran. Perhaps if the Bush administration practices better leadership, all this could have been avoided. For the soldiers on the ground like Jocko Willink and Leif Babin, extreme ownership could win the Battle of Ramadi but not the Iraq War.

History

Crashed - Adam Tooze

Crashed is a thick book that covers the Great Recession and its aftermath. In particular, the book connects the 2008 recession and Eurozone crisis, blaming it on Europe’s lackluster response to the 2008 recession. The radical intervention by the United States and China to save their economies were not made by Europe in 2008, whose banking sector and overall economy were weaker in the early 2010s. At the same time, any stimulus taken was beyond the capacity of smaller European states. Financial crisis became fiscal crisis for European countries. This connection was seldom made in the news coverage of Eurozone crisis, which blamed Southern European excess for their predicament.

The Great Recession is the probably most significant historical event of my lifetime. For one, it was the worst economic recession in 80 years. Millions of Americans were impoverished. It’s cause by careless technocratic elites and unequal resolution by the same technocracy generated a swell of populist anger. This anger was channeled into populist political campaigns on both sides of the Atlantic. Across the Atlantic, the moderate Left and Right have lost ground to their ideological flanks. These populists have all had authoritarian tendencies; democracy was damaged.

The 2010s in some ways were like a new 1930s, but unlike Wages of Destruction (which I read first), Tooze is writing history as it is happening. The book is published in 2018, covering events up to 2017. From the post-COVID perspective—another once in a lifetime crisis—we can judge Tooze’s commentary on 2008.

  • Tooze is right in noting that the 2009 stimulus in the United States was not enough. Unemployment in the United States peaked at 10%, taking 7 years to reach pre-crisis levels. Learning from this, Congress passed trillions of stimulus which went directly to households in 2020.
  • Tooze is right in calling Dodd-Frank a mess. The implicit too-big-to-fail guarantee incestuously ties the government and Wall Street together. Systematically important financial institutions have turned into arms of the state, albeit operated for private profit.
  • Tooze justly notes that inflicting austerity on the Greece only caused suffering. Even today Greece has a 15% unemployment rate and a debt to GDP ratio of 176%.
  • Tooze correctly ties the collapse in centrist politics across the Atlantic back to the 2008 recession. The inequality of the crisis-fighting measures reactivated the Left. The power wielded by unelected elites reactivated the far Right2.
  • Tooze misses the new Cold War emerging between China and the United States. Obama began an anti-China stance with the TPP and freedom of navigation in the South China Sea. Trump dug into the toolbox of tariffs to escalate the war. Biden has continued and substantiated Trump’s anti-China industrial policies.

Wages of Destruction - Adam Tooze

Wages of Destruction is an incredibly dense and long book about the German economy from 1919-1945. The book attempts to provide a strategic, ideological, and economic synthesis as an answer to many big questions about Nazi Germany.

  • What were Hitler’s geopolitical ambitions?
  • Did Hitler help Germany exit the Great Depression?
  • Why did Hitler go to war in 1939 with Western Europe?
  • Why was Germany so successful in 1940-1941?
  • How was Germany able to surivive another 3.5 years after the failure of December 1941?
  • Why dedicate valuable resources to genocide?
  • How effective was Anglo-American bombing of German industry and cities?

The answers for these questions deviates from the previous historical orthodoxy. Hitler’s desire to create a Germany capable of competing with the United States (and the UK to a lesser extent), improvisation in the face of material and labor constraints, and racial hierarchy drive much of Wages of Destruction. This desire to compete with the North Atlantic leads Hitler to the conclusion that he must conquer and genocide Eastern Europe to gain the land and labor. Along with careful management of the national economy, the Nazi state applies these tools before and during World War II to start and perpetuate the worst conflict in human history.

I am uncertain as to whether Tooze is right. Tooze’s rationalization of much of Germany’s genocidal drive and action as a reaction to the American century was certainly shocking to me. What is more certain is that the book is a hard read even for those familiar with the general course of the Second World War. There are many names of people, companies, and government agencies which, unless you too are an economic historian of 20th century Europe, will be new. Having never taken a macroeconomics course in high school or college, I had to look up terms like rationalization or balance of payments. The trouble was definitely worth it to see such a pivotal clash from a new perspective.

Programming

Clean Code - Robert Martin

Clean Code is the pre-eminant book on programming, ranked first in many lists of the books every programmer should read. It is the number one best seller on Amazon in the Software Design & Engineering category yet has also received anti-recommendations in recent years by bloggers and other authors. Given my current job as a software developer, I decided to read Clean Code to make my own opinion. I review each chapter individually.

Certain chapters are written with/by other authors.

1. Clean Code

The first chapter begins by emphasizing the importance of clean code for the small number of readers who dismiss its value. The remainder of the chapter tries to define what “clean code” means: readability, simplicity, and loftier ideals like elegance.

2. Meaningful Names - Tim Ottinger

The second chapter can be summarized “don’t make your names too long” and “don’t make your names too short”. Typing is easy; don’t be lazy and drop important context. Knowing what can be left out from variable names is harder. Err on the side of longer names as unnecessary information can always be ignored by the reader.

3. Functions

The most opinionated rule in the whole book is

The first rule of functions should be small. The second rule is that they should be smaller than that [emphasis in original].

This makes no sense to me. Isn’t extracting every few lines of code to a function is equivalent to commenting every few lines? Martin calls comments a necessary evil. Why should writing a psuedo-comment in a function name be considered a success? In my short career, I have read long classes filled with similarly named but slightly different methods like render in Listing 3-7. It is not a fun experience.

I agree that functions need a maximum size. Functions should not be longer than a screen. But, functions, at least those rarely called, need a minimum size limit too. Functions should do only one thing, but that thing needs to be significant. Functions incur a cost. They disrupt the linear flow of the code, increase the interface surface area, and introduce coupling between modules. Their benefit needs to be greater than the code.

Otherwise, the advice in the chapter is good. The number of function arguments should be minimized. A large number of arguments makes writing unit tests annoying. Avoiding code duplication is important, but don’t over do it. Deduplication is not worth the wrong abstraction. The preference for exceptions instead of error codes is ironic as some modern languages like Rust and Go do not have exceptions.

4. Comments

Martin hates comments.

Comments are always failures

(which negatively influences his philosophy around functions and classes). I mostly agree, mainly since old comments tend to linger in the code base, even if more for sociological reasons than practical ones. Good comments are valuable though. I hope Martin’s statements doesn’t deter readers from attempting to write good comments.

Martin’s classification of good and bad comments looks good to me. His advice against HTML comments is out of date as IDES/editors render stylistic markings now when hovering over the documented entity.

5. Formatting

This is the first chapter I whole heartedly agree with. It formalizes all the rules I intuited over the years from writing large programs. The penultimate section of the book hits a gold nugget. Configure IDE/editor tools to enforce formatting standards for you, and you will never have to think about formatting again.

6. Objects and Data Structures

Martin draws a distinction between objects which only expose their methods and data structures, better called structs, which expose their fields.

  1. Adding a new area function for Circle, Rectangle, and Square structs requires creating only 1 function, albeit with 3 different area formulas. Adding a new area method to Circle, Rectangle, and Square objects means modifying 3 classes.
  2. Adding a new Triangle struct forces us to modify all our geometric functions: area, perimeter, etc. Adding a new Triangle object doesn’t require changes to another other objects.

Essentially, Martin argues that object oriented and procedural code are complimentary. It’s an interesting idea, although it feels like the only difference is how the functions are grouped. Underneath, we still need $n_{functions} \cdot n_{shapes}$ formulas.

7. Error Handling - Michael Feathers

Overall, this chapter covers the basics of clean error handling in Java. The “Don’t Pass Null” section hits on a core idea from A Philosophy of Software Design—defining errors away. Adjusting code so that it never returns an error is the cleanest error handling.

As for passing nulls, the solution is better language design. Languages post 2008 often disallow ordinary objects from being null. Only nullable types can be null. The compiler can check whether nullable types are being assigned to non-nullable types and throw a compile time exception when there is a risk of a NullPointerException.

8. Boundaries - James Grenning

This chapter advocates wrapping external dependencies in a module m. Application code only uses m, pushing all boundary code interacting with third party packages into m. Especially if the application code uses the external package in a few specific ways, I highly recommend doing this. Using adapters and wrappers this way is something I started unconsciously, so it’s nice to surface this principle to the level of conscious thought.

9. Unit Tests

Martin advocates for test driven development (TDD) where tests are written first. Only after a test is written, the developer is allowed to write production code to make the test pass3. Given that TDD is not widely practiced and that its efficacy at building better software is contested by empirical academic research, TDD material probably should have been cut to keep the chapter relevant to as broad of an audience as possible.

The chapter also gives the strange advice to invent a domain specific language just for testing. Personally, I prefer Listing 9-3—which the author calls bad—to Listing 9-4. The name wayTooCold is not a verb phrase; I find it hard to interpret the 5 character string representation of hw’s state.

Otherwise, the advice in the chapter is good. Test suites are important to working software. Unit tests should follow the setup, operate, check structure. Tests can have multiple asserts but only a single concept. All tests should follow the FIRST principles. I wish the book had covered mocking which is essential to unit testing classes in Java.

10. Classes - Jeff Langr

This chapter offers good advice for breaking up large classes. I agree more with the small classes advice than the small functions advice. Classes become large by having more methods which increases interface costs without providing much more functionality. In fact, having fewer but deeper methods helps keep classes smaller by reducing the number of methods. Each class should have a single responsibility it does well.

11. Systems - Kevin Wampler

This chapter emphasizes the role of dependency injection (DI) and aspect oriented programming (AOP) for clean systems.

  1. DI is important whenever writing large applications. It allows classes to use dependency objects in fields without worrying about their origins. For Java, I recommend Dagger over Spring or Guice4.
  2. Often the same code needs to be run in many places. An example is timing every method $f$ and publishing the results to a dashboard. AOP lets us wrap $f$ with our timing code rather than put it into $f$. Every call to $f$ first goes to a timing proxy that starts the timer, internally calls $f$, then publishes $f$’s execution time. The explanation of AOP is really good. This is the first time I felt like I grasped the concept.

DI and AOP are useful tools to construct clean systems but are not panaceas to the problem of clean coding.

12. Emergence - Jeff Langr

This is a weird chapter. It mentions 4 rules of simple design, then tries to show how applying those rules creates a design out of thin air. It advocates no duplication when a little duplication is ok. The section “Minimal Classes and Methods” even acknowledges this.

13. Concurrency - Brett Schuchert

This chapter provides recommendations clean concurrent programming. I don’t have much experience writing multithreaded code, but I really like this chapter. Java is way past version 5 now, so some of the advice may be out of date.

14. Successive Refinement

In this chapter, Martin works through an example refactoring of a rough draft of an Args class to a clean version. The Args class parses command line arguments according to a one line String schema. The final implementation is mostly ok, but has a few problems.

  • Deciding which marshaler to add based on the schema type symbols should be split into its own method outside of the Args class.
  • Why make getValue a static method in ArgumentMarshaler? If the data is stored in a field, why not make getValue a regular method.
  • ArgumentMarshaler’s set method should take a String instead of an Iterator<String>. ArgumentMarshaler doesn’t need to know that the arguments are being iterated over, just the current argument. This issue can be partially fixed by using a for-each loop
  • currentArgument shouldn’t be a field.

I find code in paper books hard to read. The refactoring of Args would be better as a companion video than a chapter.

15. JUnit Internals

Martin refactors the class ComparisonCompactor from the JUnit library which creates an error message showing the difference between 2 Strings. I like the final version more than the final implementation of Args. My only complaint is that Martin has a disturbing tendency to use fields like global state. One method will set a field for another method to read it. In this example it is not so bad. Each field isx written in only 1 method while being read by many others. But this tendency flares up in other listings throughout the book.

16. Refactoring SerialDate

Another chapter refactoring code. SerialDate is a class deep inside the no longer developed JCommon library. Martin heavily criticizes this SerialDate class5. This is the most realistic refactoring as Martin tries to fix a poor module than improve an already good one. It is rare to refactor good modules to become great. The chapter doesn’t print the original or final version of SerialDate so Martin’s steps are difficult to follow.

17. Smells and Heuristics

This is the best chapter in the book. It summarizes the content of all the previous chapters in $5 + 4 + 36 + 3 + 7 + 9 = 64$ principles. Some principles like G4: Overridden Safeties are mentioned in the rest of the book. After reading the entire book (minus the Appendix), I would recommend newbie programmers just read Chapter 17. Overall, the book isn’t as bad as the naysayers claim, but there is questionable information. After reading Chapter 17, I would then recommend newbies read A Philosophy of Software Design.


  1. What this might imply is left as an exercise to the reader. 

  2. I find the connection between the ruin of the 2008 recession and the rise of Trump less believable given that Trump voters were better off than the average voter. 

  3. The developer can refactor code while keeping the tests passing. 

  4. Both Guice and Dagger v2 are developed by Google. Dagger v1 was developed by Square, the company that sells those point of sale tablets. According to a Reddit AMA, Google plans to replace Guice with Dagger but, as of 2022, both are actively developed. 

  5. His first move is to rename it to DayDate. 




If you found this useful, please cite this as:

Pu, George (Dec 2022). 2022 in Books. https://georgerpu.github.io.

or as a BibTeX entry:

@article{pu20222022-in-books,
  title   = {2022 in Books},
  author  = {Pu, George},
  year    = {2022},
  month   = {Dec},
  url     = {https://georgerpu.github.io/blog/2022/books/}
}



    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • The Inflection Point of the Exponential Function
  • 2023 in Film
  • Blogging for 4 Years
  • Economic Possibilities for Ourselves
  • Solution to Why π is in the normal distribution (beyond integral tricks)