KRIS SHAMLOO

thirty Warhammer 40K book reviews

2025-10-16

Two years ago I was new to the Warhammer 40K setting and I wanted to check out the universe. I'm mostly interested in books, I don't play the tabletop game.

So where to start? Lots of folks online recommend the Eisenhorn series as a good starting point. I mostly agree but you can safely start with any stand alone novel or first entry in a series. No one novel will communicate the breadth and depth of the setting, so no matter where you start you'll have some "oh what's that?" type questions or even misconceptions.

For example, in Eisenhorn the first Astartes (Space Marine) you encounter is from the Emperor's Children faction. I found this incredibly confusing at first because the Astartes was presented as a bad guy (i.e. against the Imperium). But how could that be, they are literally named "Emperor's Children"? Surely that's the name of a pro-Imperium faction. Incorrect! The Emperor's Children are not pro-Imperium and from the point of view of Eisenhorn are definitely baddies. No matter where you start there's just too much world already built for you to not have misunderstandings, and that's part of the appeal.

Okay let's do a blitz of the 40K novels I've read so far.

Eisenhorn 1-3 (Omnibus): very fun secret agent/detective stories. Great starting point. You will become very concerned about Eisenhorn's decision making!

Horus Heresy 1 (Horus Rising): The pedants will say its a Warhammer 30K novel. Nice intro to the Horus Heresy series and you can really tell they were expecting this to be about a dozen books or so. Goes down smooth with the right amount of grandeur, like a mythical milkshake.

Horus Heresy 2 (False Gods): This is when Horus decides to heresy, it's a fine continuation of Horus Rising. Really strong scene of Horus's closest Space Marine troopers taking him to medical through a large crowd.

Horus Heresy 3 (Galaxy in Flames): My favorite of the early Heresy books. Uses the dramatic irony of the audience knowing the heresy is going to happen (but the characters do not) the best. Has a few scenes that remind you this is a tabletop setting where named characters are in a no-survival scenario yet manage to survive.

Horus Heresy 4 (The Flight of the Eisenstein): A fantastic action-movie plot undermined by the unbearable dullness of Garro.

Horus Heresy 5 (Fulgrim): Hey remember how I was confused about the Emperor's Children from Eisenhorn? I'm not confused about that anymore. I'm confused about other, FAR WORSE things now instead.

Ok after those five Heresy Books I needed a break from this universe. I read a few other things before I heard the cherubic choir calling me back. I was still on the fence about how deep to go into the Heresy series so I decided to return to some 40K books.

Carcharodons Red Tithe: Space Sharks versus Space Edgelords! The same kind of dumb fun as when you're a kid having stick fights with the other kids.

Salamanders Omnibus: Salamanders are so cool and yet this was the first 40K book I just couldn't bother to finish. I think I read the first book in the Omnibus but stopped about halfway through the second.

The Devastation of Baal: There are a lot of named characters here that I had to look up. Nevertheless, I love me some Blood Angels. I'm surprised how well the Tyranid POV sections worked.

Sanguinius The Great Angel: If you like Sanguinius you'll like this well enough. Nice tie-ins to other Heresy books. By Warhammer law everyone has to pick their favorite primarchs and I love Sanguinius and Corax. Gimme my beautiful sad bird boys!

I read the Siege of Terra back-to-back so these next mini reviews might bleed into one another.

Siege of Terra 1 (The Solar War): Ok we're back to the Horus Heresy proper. I decided I was not going to read all the Heresy books so I skipped straight to the Siege. I enjoyed the naval space combat and would start to miss it in later books.

Siege of Terra 2 (The Lost and the Damned): The traitors are landing! Abaddon is getting the ick from Horus! Katsuhiro please continue to ground me from these melodramatic transhumans.

Siege of Terra 3 (The First Wall): Fun book about Perturabo v Dorn. My favorite primarch power couple. Fun sub plot about a human fighter named Zenobi.

Siege of Terra 4 (Saturnine): Possibly the most entertaining grand sci-fi war novel ever written. Completely sells the scale of the siege while following a few critical characters. Three distinct flavors of battle, highlighted by Abaddon's Saturnine gambit.

Siege of Terra 5 (Mortis): This one dragged along.

Siege of Terra 6 (Warhawk): Shiban Khan rules. Jaghatai Khan rules. The White Scars rule. The Death Guard are delightfully wretched. Giant flying saucer shield? Yes please.

Siege of Terra 7 (Echoes of Eternity): Look I'm a sucker for Sanguinius content so this one is peak. Absolutely everything is completely fucked. Everyone involved knows this and they're all the more real for holding the line away. Vulkan, my boy, lives. Sanguinius cements his place as the number one primarch forever. My favorite book of the Siege and of the Horus Heresy series. Zephon you can bring me sorrow anytime bud.

Siege of Terra 8-10 (The End and the Death): By this point I have a better understanding of the 40K setting. As a writer I am all too aware that writing this ending is a nigh impossible task - yet Abnett succeeds. This one is weird, it's silly, it's impenetrable, it's how it had to be. Sanguinius does what he must. The Emperor does too. Some of it is cheesy, some is genuinely moving, really impressed with what Abnett pulls off here.

Siege of Terra 11 (Era of Ruin): I have this one in hardcover and I gotta say those Games Workshop folks know how to print a gorgeous book. Lots of nice short stories. Shiban Khan continues to rule.

Horus Heresy 14 (The First Heretic): Theoretical: Lorgar sucks.

Horus Heresy 19 (Know No Fear): Practical: Guilliman punches a dude's head off.

Oaths of Damnation: Tightly focused and very grim. This book is elevated by the fact that The Exorcists are a really interesting chapter but it's just lots of fighting.

Roboute Guilliman Lord of Ultramar: Don't bother.

Brothers of the Snake: Just barely enough human characters to make this a sufficiently grounded Space Marine book. Does a cool job of starting with a small conflict and roughly doubling it over and over.

Pariah: Another secret agent story like Eisenhorn but with a more likable protagonist.

Spear of The Emperor: No joke this is probably the best Space Marine book - maybe even the best 40K book I've read. It's restrained, there are tons of normal (for 40K) humans to ground the story. Author Aaron Dembski-Bowden writes a fantastically paced story that grows with the steady inevitability of and incoming tide. Redden the earth.

Ok I think that's all the ones I've read so far! If you are brand new to the setting you can't go wrong starting with Eisenhorn but if you want to enter the universe from a different angle I might start with Spear of The Emperor or Brothers of the Snake.

three flavors of my favorite productivity system

2025-05-04

There is a genre of content out there that is obsessed with productivity systems. For a short while I was a big fan of this genre. I want to get things done, I want to accomplish tasks; if I implement these systems I could become prolific! I won't be so bold as to say all the productivity people are bullshitters; but there are smells. There is a common trap that productivity people fall into. A pattern of being unproductive in the goal area and very productive in executing, tweaking, refining, implementing, experimenting, discussing, and evangelizing productivity systems.

My system is this. First, work on the task every day. Second, at the end of working on the task leave yourself a hint as to where to pick up the next day. That's it in its entirety. The only thing that meaningfully helps me be more productive is preserving and encouraging momentum.

Here are three variations of this system in the context of a software engineering project.

Flavor 1: TODO NEXT comments. When using this approach I leave the occasional TODO comment in the codebase for things that stick out to me that may need work at some point in the future but not now. The TODO NEXT comment is the special one, there should only be one of these comments and you should add it at the end of a work session. Next time you begin working read that comment and giddyup.

Flavor 2: Next: commit messages. At the end of a work session the code is committed with a commit message that describes the change. At the end of the commit message is an additional line of text: "Next: benchmark changing the foo data from a list to a dictionary". I really enjoy this one in practice. Something about creating that last commit really wraps up the work session nicely. When you come in for the next session read the previous commit message and get started.

Flavor 3: Pen & paper. I've used all three approaches but writing things down is the most flexible and the most physically satisfying. I'm a sucker for stationary so your mileage may vary. At the end of the work session I write down a note about what to start working on next. When I sit down to work on the project again I read that note and get started.

opinions about Go, Rust, and Swift but each time the word count doubles

2025-03-16

[ one word ]

Go: ez
Rust: robust
Swift: Apple

[ two words ]

Go: comfy tooling
Rust: borrow checker
Swift: nice enums

[ four words ]

Go: small language big impact
Rust: genius, possibly too genius?
Swift: progressive disclosure mostly works

[ eight words ]

Go: Occasional slice footguns, suspiciously productive language all considered.

Rust: Fearless concurrency is not just a catchy slogan.

Swift: The String API should not be this annoying.

[ sixteen words ]

Go: The slices package made generics worth it for me, but I would have been ok without.

Rust: A genuine step change in what a language can offer for safe, correct, and fast programs.

Swift: Two unforced errors: an overly complex type system, SwiftUI syntax/errors via Result Builders is inscrutable.

[ thirty-two words ]

Go: I'll always be a Python guy at heart but for most small programs I reach for Go. Some minor flaws cause an outsized reaction online. Top two missed features: enums and tuples.

Rust: Ultimately Rust's strictness is anathema to my exploratory development style. I've only found joy writing Rust when rewriting programs with known data structures/algorithms. I love running Rust programs but not Rust.

Swift: I am a fan. I really enjoy app and game development in Swift. I question the evolution of the language, Swift 6 in particular feels like another Python 2 to 3 situation.

how to be a hotter software engineer

2025-03-09

1. Prioritize your health. You can't be hot without a crisp jawline. If you are not getting quality sleep you are leaving engineering brainpower on the table. Same thing goes for diet and exercise. This is very well studied: being fit makes you smarter. In addition to peak brain power; being fit will let you work for longer durations. Being fit will allow you to get your core work done faster and leave you with the stamina to continue working on other things (like fun side projects).

2. Pull on threads. Three of three LLMs agree*: openness is super hot. Read the standard library of the programming languages you are using. Read the docs of the libraries you're depending on. Ask folks around about what they think the system is doing and what they think it is supposed to be doing. Experiment with new technologies. Dig through the layers of abstraction your system is built on. Abstraction layers are always a little bit leaky. The ability to hop up and down layers will give you a better grasp of the system as a whole. Regularly ask yourself: how does this work? Why was it built this way?

3. Change your perspective. Scoot back a little from your screen and widen your view. Find the hottest angle. What are you trying to actually accomplish? What is the team goal? The company goal? What is your goal? If you don't change anything how will things look in a year? Don't just consider the programs or systems you're engineering when thinking about these questions. Jobs have turnover: you might have new colleagues in a year. Technology has hype cycles: you might not being working on LLM integrations in a year. Markets ebb and flow: will your company still be making money in a year? These are essential questions to help you steer your career and your life. Knowing where you're going is super hot.

I'll leave you with one last thing. Please remember that software is written for people, not computers. Hotness is for the people.

---

*[1] ChatGPT, Claude, and Gemini were asked the following prompt: "In the context of the big five personality traits: is openness to experience important to being super hot?"

presentation tips

2025-01-25

1. Be entertaining. I'm a huge dingus, but if I'm funny I might be able to cast a spell on my audience. Corporate work is often dull. One or two jokes goes a long way to helping lighten the mood. Minimum of one joke, max three. Jokes don't have to be complicated, self deprecating is safe.

2. Remind folks of the team goal. Everyone gets tunnel vision at work around how they do their little part of the process. The goal is rarely to execute steps in a process; it's usually to make a great product or service. Tie it in to what you're presenting.

3. Less text, more rehearsing. Keep your slides sparse. Watch a Steve Jobs keynote. He was the best at it. His slides are spartan, he talks a lot. If you struggle with speaking, present to your manager (or a colleague) in private. Ask them to time you. Ask them to give you feedback at the end. Was the message clear? Was it boring? This is a win-win: you get to practice and your manager gets to do something unambiguously helpful.

the unreasonable effectiveness of turning it off and on again

2025-01-19

There is a good reason the most common troubleshooting step for a tech problem is to restart the device: it often works. Why might that be? The explanation is actually pretty simple. Software is default blind.

Default blind means that software has no clue what it's doing.

Running programs charge forward recklessly. Software has no visibility into itself or anything on the system unless it has been explicitly programmed to look. There is no default level of awareness, everything must be explicitly checked. If a program doesn't check for an error condition, the program might behave incorrectly. If the program checks for ten error conditions and you hit an unexpected eleventh: trouble!

Hundreds of programs are involved in something as pedestrian as listening to music with wireless headphones. These programs run best in an unsullied environment. Nothing to metaphorically trip over.

The perfect program doesn't exist. So as your music player runs, bugs occur. Big bugs are easy to spot and fix. It's the little insidious ones that get shipped to customers. These little bugs don't stop your music listening directly. Rather these bugs mess up the computing environment. They leave a file open; they allocate a little too much memory; they fill a queue somewhere faster than it's getting drained.

Eventually, if enough buggy programs mess up the computing environment enough, an essential program in your music-listening chain will fail. This is where restarting the device comes in.

Restarting the device wipes the slate clean, the programs we want to run are now more likely to be running in the clean "happy path" environment they were programmed to run in.

The program you're directly running might not be to blame. A good programmer can only be so defensive. If another program starts consuming massive compute resources in the background, the user might blame the foreground application even though it's innocent. Restarting the computer stops the bad background application "fixing" the perceived problem with the foreground application.

Software often seems clever because of how powerful it is. But even in the era of LLMs these are not thinking machines: they're explicit instruction machines. Unexpected state accrues on a running system like dust. Restarting the machine clears the figurative dust, resetting the compute environment to what the program is expecting.

Oh and don't forget to get a good night's restart for the computer user.