Archive
1046 posts · Page 85 of 88. ← Blog
Module 2 introduced closures as anonymous functions that capture their environment. But once you start passing functions around as values — storing callbacks, building higher-order APIs, returning behavior from functions — a few subtleties surface: functions and closures aren't quite the same type, returning a closure requires a boxing trick, and the `Fn` trait family has a precise structure worth knowing. These details show up constantly in real Rust APIs, and mastering them makes you fluent in Rust's functional side.
Module 2 introduced closures. But once you start passing functions around as values — callbacks, higher-order APIs, returning behavior — subtleties surface: functions and closures aren't quite the same type, returning a closure requires a boxing trick, and the Fn trait family has a precise structure worth knowing.
No language is an island. Decades of critical software — operating systems, libraries, codecs, crypto — is written in C, and any systems language that couldn't talk to it would be dead on arrival. Rust's foreign function interface lets it call C code (and be called from C), which is essential for interoperating with the existing world and for adopting Rust incrementally into C/C++ codebases. Crossing that boundary means leaving Rust's safety guarantees behind, so FFI is inherently unsafe — but it's a controlled, well-defined kind of unsafe.
No language is an island. Decades of critical software is written in C, and any systems language that couldn't talk to it would be dead on arrival. Rust's foreign function interface lets it call C (and be called from C) — essential for interoperating with the existing world and adopting Rust incrementally.
There is a keyword in Rust that feels almost heretical given everything the language stands for: `unsafe`. It exists because Rust's safety guarantees, powerful as they are, are necessarily conservative — the compiler rejects some things that are actually fine, and some low-level operations (talking to hardware, calling C, building certain data structures) genuinely require capabilities the safe subset forbids. `unsafe` is the escape hatch, and understanding it — what it does, what it doesn't, and how to use it responsibly — completes the picture of how Rust achieves safety.
There is a keyword in Rust that feels almost heretical: `unsafe`. It exists because Rust's safety guarantees are necessarily conservative, and some low-level operations genuinely require capabilities the safe subset forbids. Understanding it — what it does and doesn't do — completes the picture of how Rust achieves safety.
Rust's type system has a few corners that don't come up in beginner code but explain things you've quietly wondered about — why some functions "return" a type that isn't really a type, why `str` behaves differently from other types, and how to give a complicated type a readable name. These advanced type features are small individually but together deepen your understanding of how Rust's type system actually works, which pays off when reading real code and library internals.
Rust's type system has a few corners that don't come up in beginner code but explain things you've quietly wondered about — why some functions 'return' a type that isn't really a type, why `str` behaves differently, and how to give a complicated type a readable name.
Traits are Rust's core abstraction mechanism, and Module 2 covered the essentials — but the trait system has more depth that shows up constantly in real code and library APIs: associated types that make traits cleaner than generics, operator overloading, traits that build on other traits, and a pattern that lets you work around Rust's coherence rules. This module goes beyond the foundations into the advanced features you'll meet in serious Rust, starting with the corners of the trait system.
Traits are Rust's core abstraction, and Module 2 covered the essentials — but the trait system has more depth that shows up constantly in real code: associated types that make traits cleaner than generics, operator overloading, traits that build on other traits, and a pattern for working around Rust's coherence rules.
Passkeys are FIDO2; FIDO2 is the spec; Ed25519 is the signature algorithm. The full registration + assertion flow in 200 lines of stdlib Go.
Services need identity too, not just users. SPIFFE issues SVIDs (verifiable identity documents) to workloads; SPIRE is the reference issuer. The shape and the first deploy.
Two signals do most of the work for detecting compromised sessions: impossible travel between consecutive logins, and credential-stuffing density across an IP range. The Go implementation.
Vector search treats every chunk as independent. GraphRAG models the relationships between entities, communities, and concepts. For corpus-spanning questions ("what's the relationship between X and Y"), graph wins.
BigQuery has had a built-in knowledge graph since 2024. For entity resolution across millions of rows — the "is this John Smith the same as that John Smith" problem — it's the cheapest tool I've found.
Embedding a question and embedding an answer often produce different vectors. HyDE generates a hypothetical answer to the question, embeds *that*, and retrieves on it. Retrieval quality goes up disproportionately.
Naive RAG retrieves on every query. Self-RAG decides whether to retrieve. CRAG decides whether the retrieved content is good enough or needs corrective retrieval. Two papers; both worth implementing.