Logo
Logo
249 results for
  • You will write a macro that compiles, runs, and produces the wrong output. You’ll stare at the macro definition, convinced it’s correct. You’ll re-read the pattern matching rules, check the repetition operators, verify the fragment specifiers — everything looks right. And then you’ll expand the macro and realize it’s generating something completely different from what you imagined. This has happened to me more times than I’m willing to admit.

    Macro debugging is a different skill from regular debugging. You can’t set breakpoints in macro expansion. You can’t step through it. You have to see the generated code, and then reason backwards from there to figure out where the pattern matching went wrong.

    Rust tutorial rust macros metaprogramming Created Fri, 14 Feb 2025 11:05:00 +0000
  • This is the lesson that ties everything together. Over the last 19 lessons, we’ve built up from mental models to executors, from channels to cancellation safety. Now it’s time to put it all into a production-grade architecture.

    I’ve run async Rust services handling tens of thousands of requests per second. The patterns in this lesson are the ones that survived contact with real traffic, real failures, and 3 AM pages. Nothing theoretical here — just battle-tested code.

    Rust tutorial rust async tokio Created Wed, 12 Feb 2025 17:09:33 +0000
  • I once spent an embarrassing amount of time debugging a macro that worked perfectly in one file and broke in another. Same macro, same input, different behavior. Turned out the expansion was referencing a variable called result — which happened to shadow a result variable at the call site. The macro was hygienically correct in isolation but collided with the caller’s namespace. That’s when I actually understood what “macro hygiene” means and why Rust only gets it partially right.

    Rust tutorial rust macros metaprogramming Created Wed, 12 Feb 2025 16:10:00 +0000
  • A data race is a memory safety bug. Two goroutines access the same variable without synchronization, at least one is writing, and the Go memory model makes no guarantees about what happens. In practice: values get corrupted, counters drift, maps panic at runtime. These bugs are intermittent — they appear under load, on fast machines, during deploys — and they’re nearly impossible to reproduce deterministically.

    The Go race detector is one of the most powerful debugging tools in any language ecosystem. It instruments every memory access at the compiler level and reports races precisely: the exact goroutine stacks at the moment of the conflicting accesses. But it only helps if you run it. Most teams run it once after a bug report. The right approach is running it on every PR, in CI, before the code is ever merged.

    Go tutorial golang deployment devops Created Wed, 12 Feb 2025 00:00:00 +0000
  • Async code is harder to test than sync code. Not because the logic is more complex, but because time, I/O, and concurrency introduce non-determinism. A test that passes 99 times and fails on the 100th is worse than a test that always fails — at least the always-failing test tells you something.

    I’ve developed a set of patterns for testing async Rust that eliminate flakiness. The key insight: mock the things that make tests non-deterministic (time, network, randomness) and let everything else run for real.

    Rust tutorial rust async tokio Created Mon, 10 Feb 2025 11:28:56 +0000
  • There’s a point when writing declarative macros where the syntax stops feeling like Rust and starts feeling like regex for code. You’re stacking repetition operators, nesting captures inside captures, and using tt munching to parse things the macro system was never designed to parse. It’s weird, it’s powerful, and once it clicks, you’ll wonder why you ever wrote boilerplate by hand.

    Repetition Operators Deep Dive

    We touched on repetition in the last lesson. Now let’s get into the mechanics that actually matter when you’re building non-trivial macros.

    Rust tutorial rust macros metaprogramming Created Mon, 10 Feb 2025 08:30:00 +0000
  • Input validation is one of those problems that looks solved until you realize you are writing the same type of check — not nil, min length, valid email format, required when other field is set — dozens of times across dozens of handlers. Centralizing these rules without reflection means either a massive switch statement or hand-writing a validation function for every struct in your application. Reflection makes it possible to declare validation rules once, at the struct, and enforce them automatically everywhere that struct is validated.

    Go tutorial golang reflection Created Mon, 10 Feb 2025 00:00:00 +0000
  • Debugging async code with println! is like debugging a highway pileup by asking each car individually what happened. You get disconnected fragments — “I was going north,” “I hit something,” “I heard a crash” — but no coherent story. With 500 concurrent tasks all writing to stdout, good luck finding which log line belongs to which request.

    The tracing crate solves this. It gives you structured, contextual logging that follows your request across tasks, .await points, and even service boundaries. I switched from log to tracing three years ago and haven’t looked back.

    Rust tutorial rust async tokio Created Sat, 08 Feb 2025 15:43:29 +0000
  • The first macro I ever wrote was a disaster. I wanted a shorthand for creating HashMaps — something like map!{ "a" => 1, "b" => 2 }. The macro compiled. The expansion was garbage. I didn’t understand fragment specifiers, I didn’t understand repetition, and I definitely didn’t understand why the compiler kept telling me “unexpected token.” Took me a full weekend to get it right. Let me save you that weekend.

    Rust tutorial rust macros metaprogramming Created Fri, 07 Feb 2025 14:45:00 +0000
  • I’ve been hand-waving around Pin for 16 lessons. Every time we saw Pin<&mut Self> in a poll method, I said “don’t worry about it.” But now it’s time to worry about it, because without Pin, async Rust’s entire safety model falls apart.

    The good news: the mental model is simpler than it looks. The bad news: the syntax is still ugly. Let’s deal with both.

    The Problem Pin Solves

    When the compiler turns your async fn into a state machine, it needs to store local variables across .await points. Sometimes those variables reference each other:

    Rust tutorial rust async tokio Created Thu, 06 Feb 2025 08:27:44 +0000