Logo
Logo
366 results for
  • I used impl Trait for months thinking it was just syntactic sugar for generics. “It’s the same as a type parameter, right? Just shorter?” No. It’s fundamentally different, and understanding how it’s different unlocks patterns that are genuinely impossible with plain generics.

    Let me show you.

    Two Positions, Two Meanings

    impl Trait means completely different things depending on where you use it:

    // Argument position: "I accept any type that implements Iterator"
    fn count_items(iter: impl Iterator<Item = i32>) -> usize {
        iter.count()
    }
    
    // Return position: "I return some specific type that implements Iterator,
    // but I'm not telling you which one"
    fn make_numbers() -> impl Iterator<Item = i32> {
        (0..10).filter(|x| x % 2 == 0)
    }
    

    In argument position, the caller chooses the concrete type. In return position, the function chooses — and the caller can’t see what it picked. These are fundamentally different concepts from type theory.

    Rust tutorial rust type-system advanced Created Tue, 09 Sep 2025 07:28:00 +0000
  • Go has two visibility levels: exported (starts with a capital letter) and unexported (doesn’t). Most engineers use only these two. But there’s a third option that the language gives you for free, and it’s more useful than most people realize. The internal directory enforces that certain packages can only be imported by code within your own module — and the compiler, not documentation or convention, does the enforcing.

    Exported symbols are API commitments. Once something is exported and external code is depending on it, changing it is a breaking change. The internal package is the escape hatch: share code across multiple packages in your own codebase without accidentally publishing an API surface you’ll have to maintain forever.

    Go tutorial golang Created Mon, 08 Sep 2025 00:00:00 +0000
  • Every time someone on Reddit says “Rust can’t do higher-kinded types,” a part of me wants to respond with a 200-line code block that proves them… well, partially wrong. Rust doesn’t have native HKTs, that’s true. But the workarounds are surprisingly expressive, and with GATs (generic associated types) now stable, we can get most of what you’d want from HKTs in practice.

    Let me walk you through the problem, why it matters, and the patterns that let you work around it.

    Rust tutorial rust type-system advanced Created Sun, 07 Sep 2025 19:03:00 +0000
  • Transactions are the part of database programming where “it’s fine most of the time” really isn’t good enough. A buggy SELECT just returns wrong data. A buggy transaction can leave your database in a half-written state — an order placed without inventory decremented, money debited without the transfer completing, a user created without their profile record. The bugs are subtle, often don’t manifest in testing, and only show up in production when two things happen at the same time.

    Go tutorial golang database Created Sun, 07 Sep 2025 00:00:00 +0000
  • I once spent three days debugging a distributed system where two services were sending messages in the wrong order. Service A expected a handshake acknowledgment before data, but Service B had been refactored to send data first. Both services compiled, both passed their unit tests, and both exploded in production. The protocol contract existed only in a Google Doc that nobody had updated.

    Session types fix this. They encode the entire communication protocol in the type system — who sends what, in what order, and when. If you violate the protocol, your code doesn’t compile. Period.

    Rust tutorial rust type-system advanced Created Fri, 05 Sep 2025 10:45:00 +0000
  • Knapsack is one of those patterns that shows up in disguise constantly. You’ll see problems framed as “partition this array,” “find a subset with sum X,” “assign +/- signs to get target T” — and underneath each one is the same fundamental structure: for each item, decide whether to include it or exclude it.

    The standard 0/1 Knapsack is the reference problem. Every variant is a modification of it: different objective functions (count instead of max value), different constraints (exact sum instead of capacity), different item usage rules (unbounded instead of once). Once you internalize the base pattern, the variants fall into place.

    fundamentals interviews Created Fri, 05 Sep 2025 00:00:00 +0000
  • The first time I implemented a connection pool that couldn’t be misused — not through discipline or documentation, but because the compiler physically rejected invalid state transitions — I felt like I’d discovered a cheat code. Not a runtime check. Not an assertion. A straight-up compiler error if you tried to read from a connection you hadn’t authenticated yet.

    This is the typestate pattern taken to its logical extreme. In Lesson 1 we saw the basics with PhantomData and builder states. Now we’re going to encode full multi-state machines where every transition is checked at compile time. No runtime overhead. No state field to match on. Just the type system doing its job.

    Rust tutorial rust type-system advanced Created Wed, 03 Sep 2025 14:17:00 +0000
  • There’s a pattern that comes up constantly in backend services: make N concurrent calls, collect all their results, and if any one of them fails, cancel the rest and return the error. This is the “all succeed or all cancel” pattern — and before errgroup, implementing it correctly required a non-trivial amount of boilerplate involving WaitGroup, error channels, and manual context cancellation. People got it wrong often enough that errgroup was created specifically to handle it.

    Go tutorial golang concurrency Created Tue, 02 Sep 2025 00:00:00 +0000
  • I remember staring at a struct definition in a library I was reading — it had a field of type PhantomData<T> and I thought, “this does literally nothing.” The field takes up zero bytes. It has no runtime representation. Why on earth would you put a field in a struct that doesn’t exist at runtime?

    Turns out, zero-sized types are one of the most powerful design tools in Rust. They let you embed meaning into the type system without paying a single byte of overhead. Once you get this, you’ll start seeing ZSTs everywhere — and you’ll start using them yourself.

    Rust tutorial rust type-system advanced Created Mon, 01 Sep 2025 08:32:00 +0000
  • Last quarter I inherited a Python data pipeline that prepared training data for our recommendation model. It processed 50 million rows. Took 3 hours. Used 64GB of RAM. Everyone accepted this as normal — “big data is slow.” I rewrote it in Rust with polars. Same data. 4 minutes. 6GB of RAM. My teammates thought I was lying until they ran it themselves.

    Polars isn’t just “pandas but faster.” It’s a fundamentally different approach to DataFrame operations — lazy evaluation, query optimization, true parallelism, and a Rust-native API that makes data pipeline code genuinely pleasant to write.

    Rust tutorial rust ai llm Created Sat, 30 Aug 2025 14:15:00 +0000