Logo
Logo
  • After spending time with Raft, I found myself curious about the algorithm it was designed to replace. Paxos has a reputation: brilliant, correct, nearly impossible to implement correctly, and even harder to extend to practical systems. Leslie Lamport published the original Paxos paper in 1989, got it rejected, submitted a revised version in 1998, and it became the theoretical foundation for a generation of distributed systems. Chubby (Google’s distributed lock service), Zookeeper (the coordination service), and the precursor to Spanner all descended from Paxos thinking. Understanding why Raft was necessary requires understanding what Paxos gets right and where it falls short in practice.

    fundamentals distributed systems Created Fri, 04 Oct 2024 00:00:00 +0000
  • The first time I tried Axum, I wrote a handler that took five extractor arguments and spent twenty minutes staring at a compiler error that said my function “didn’t implement Handler.” Turns out the order of extractors matters, and there’s a limit on how many you can have. Nobody tells you that upfront. So I’m telling you now.

    Routing Fundamentals

    Axum’s router is just a struct that maps HTTP methods and paths to handler functions. No macros, no attributes — you build routes with method calls.

    Rust tutorial rust web api Created Thu, 03 Oct 2024 14:45:00 +0000
  • Every senior engineer I know makes compression decisions regularly: should this API response be gzip-compressed? Should logs be stored compressed? What compression level? Which algorithm? I made these decisions for years based on “gzip is standard, use it” without understanding why it worked or when something else might be better.

    Understanding the fundamentals of how compression works — entropy, Huffman coding, and LZ77 — changed how I think about data formats, wire protocols, and storage costs. It also helped me understand why some data compresses well and some data does not, which is critical for capacity planning.

    fundamentals algorithms Created Thu, 03 Oct 2024 00:00:00 +0000
  • After the lexer and parser, we have a tree. A beautiful, hierarchical, unambiguous representation of the program. Now we need to make it do something. The simplest way to execute a program from its AST is to walk the tree recursively and compute results as you go. No intermediate representation, no bytecode, no machine code — just a recursive function that pattern-matches on node types and returns values.

    This is a tree-walking interpreter. It is not the fastest approach (we cover bytecode and code generation in Lesson 4), but it is the most direct. Many production language implementations started here — and some, like early Ruby and Python, stayed here for a long time.

    fundamentals compilers Created Thu, 03 Oct 2024 00:00:00 +0000
  • Lessons 1 through 5 were mostly about principles. This one is about code. Specifically, the five generic implementations I’ve used in real production systems that my teammates didn’t complain about. Each one passed code review, made it into production, and held up over time.

    The pattern across all of them is consistent: the algorithm is identical regardless of the type, the duplication without generics would have been mechanical and ongoing, and the generic version is genuinely easier to read than the alternative.

    Go tutorial golang generics Created Wed, 02 Oct 2024 00:00:00 +0000
  • I spent three weeks building a service in Actix-web before ripping it out and switching to Axum. Not because Actix was bad — it’s genuinely fast and battle-tested. I switched because every time I needed custom middleware, I was fighting the framework instead of writing my application. That experience taught me something: in Rust web development, the framework you pick determines how much you fight the type system versus how much you work with it.

    Rust tutorial rust web api Created Tue, 01 Oct 2024 10:22:00 +0000
  • A few months ago I tracked down a bug where a cache TTL check was wrong because someone compared SystemTime values that had been serialized and deserialized across a system clock adjustment. The cached timestamps jumped backward, and suddenly entries that should’ve expired were “fresh” again. That’s the kind of lesson that teaches you the difference between monotonic clocks and wall clocks.

    Two Clocks, Two Types

    Rust gives you two time types because computers have two fundamentally different clocks:

    Rust tutorial rust stdlib Created Tue, 01 Oct 2024 07:50:00 +0000
  • There is a piece of Go advice that sounds almost too obvious to state, and yet I see it violated in production codebases every week: return concrete types from your functions. Not interfaces. Not interface{}. The actual, named, exported struct that your function produces.

    The reason this feels controversial is that it conflicts with object-oriented instincts. In Java and C#, returning an interface from a factory is considered good practice — it hides the implementation detail and “programs to an interface.” In Go, that instinct leads to information loss, surprise type assertions, and constructors that promise less than they deliver.

    Go tutorial golang interfaces Created Tue, 01 Oct 2024 00:00:00 +0000
  • encoding/json is one of the first packages every Go developer uses and one of the last they fully understand. The basic json.Marshal / json.Unmarshal API is approachable. But the package contains a whole layer of capabilities — custom marshaling, streaming decoders, json.RawMessage for deferred parsing, interface-type fields, and a surprising number of edge cases — that separate the code that works in demos from the code that works in production with adversarial inputs.

    Go tutorial golang stdlib Created Mon, 30 Sep 2024 00:00:00 +0000
  • I once wrote a deployment script in Bash that grew to 800 lines with nested conditionals, string interpolation bugs, and error handling that amounted to “hope for the best.” Rewrote it in Rust using std::process::Command — same functionality, but with actual error handling and type safety. The number of failed deployments dropped to zero.

    Command — The Builder

    std::process::Command is a builder for spawning child processes. You construct the command, configure it, then either run it to completion or spawn it and interact with its I/O.

    Rust tutorial rust stdlib Created Sun, 29 Sep 2024 19:15:00 +0000