type-exercise-in-rust: A Course That Builds a Typed Expression Engine, Not Just Rust Skills
Learn advanced Rust techniques by building an expression evaluation framework for a database system.
At a glance
- What is it?
- This repository is a structured course that walks you through building a vectorized, typed expression evaluation framework for databases in Rust. It focuses on the hard parts: borrowing strings without copying, null handling, type coercion, and runtime function selection.
- Who is it for?
- Adopt this if you are a Rust developer who wants to learn how to design generic, type-erased interfaces for high-performance data processing, and you prefer a hands-on, test-driven course over reading theory. Do not adopt it if you need a production-ready expression engine or if you are new to Rust traits, enums, and references.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 14, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What This Course Actually Builds and Why It Matters
The repository is not a library you drop into your project. It is a course that leads you through constructing a small vectorized expression engine for a database system. The README states that a hand-written loop for one integer function is easy, but it stops scaling when the engine must borrow strings without copying, preserve nulls, read several column encodings, coerce types, and select functions at runtime. The course solves that by building type families and checked boundaries that move those decisions out of each row loop. The target audience is a Rust programmer who already knows ordinary Cargo use, enums, traits, references, and `Option`. If you are comfortable with those, the course gives you a concrete reason to learn advanced patterns like erased enums and bound interfaces. If you are not, the setup will likely be a wall.
The Architecture: From Logical Types to Erased Enums
The course is organized into chapters, each extending the same starter project. The README lists the outcomes: you connect logical types, owned values, borrowed values, physical arrays, and checked erased enums. That is the core mechanism. You start with a typed representation of what a value is, then you build ways to hold that value as owned or borrowed, then you lay it out in physical arrays, and finally you erase the type information into an enum that can be checked at runtime. The point is that a generic code path can handle new types and operators without rewriting the execution loop. The course also covers reading nullable arrays, constants, and Indexed views without materializing a new column, which is a specific performance technique for avoiding copies. The architecture is cumulative, and the README warns that `SUMMARY.md` is the sole ordered chapter list, so you should follow the chapters in order.
Getting Started: Commands That Actually Work
The README gives a precise setup sequence. First, you fetch the repository and create a working branch: `git fetch origin`, then `git switch --create course-work --track origin/main`. The README notes that you can choose another branch name if `course-work` already exists. Then you run `cargo check -p type-exercise-starter --lib --locked` to confirm the starter baseline compiles. The course tells you to work only in `type-exercise-starter` and not to inspect `type-exercise/` or `archived/` while solving exercises. Chapter tests are copied with `cargo x copy-test --chapter 1`, then run with `cargo test -p type-exercise-starter chapter_1 --locked`. The first run should fail because the new behavior is missing. You then read the copied test file under `type-exercise-starter/src/tests/`, implement the named API in other starter files, and rerun the test until it passes. The rule is strict: never edit copied tests or `src/tests.rs`, and keep all earlier copied chapters green.
What the Course Deliberately Leaves Out
The README is explicit about the boundaries. The course stops short of Decimal arithmetic, casts, and rounding, implicit narrowing or lossy casts, nested or list-producing functions, concrete four- and five-input builtins, exhaustive fast paths, an aggregate engine, and per-row futures. That is a significant limitation if you want to build a full database expression evaluator. The course is a teaching tool, not a production framework. It gives you one representative fast path, not all of them. If your goal is to implement a real query engine, you will need to extend this design significantly. The README also notes that the course only exposes one ready future per batch through static, erased, and already-bound expression paths. So the material is deliberately narrow. That is a strength for learning, but a weakness if you expect a complete solution.
The Trade-Off: Generic Code vs. Per-Type Specialization
The course's central design choice is to use generic, erased, and bound interfaces so that new types, operators, and arities reuse the same execution path. That is a common pattern in database engines, but it comes with a cost. The README does not mention performance benchmarks, so you cannot know from this material whether the generic path is as fast as a hand-written loop for a specific type. The course explicitly says it preserves the same results and errors through one representative fast path, which suggests that the authors did not exhaustively optimize every combination. For an engineer evaluating this course, the trade-off is clear: you learn how to structure code for extensibility, but you do not learn how to squeeze out the last bit of performance for each type. If your project needs maximum speed for a narrow set of types, a hand-written loop may still be the right choice. The course is honest about that by not claiming exhaustive fast paths.
Alternatives: How This Differs From Other Rust Learning Projects
A common alternative is to learn Rust by building a small interpreter or compiler, such as a tree-walking evaluator for a toy language. That approach focuses on parsing and AST evaluation, but it rarely deals with columnar data, nullability, or type coercion across arrays. This course is different because it is specifically about database expression evaluation. Another alternative is to read database internals books that include Rust code, but those often present finished designs rather than a progression of exercises. The key difference here is the test-driven structure: you copy a test, implement the API, and move on. That forces you to write the code yourself, which is more effective for retention than reading a solution. However, the course is not a general Rust tutorial; it assumes you already know traits and enums. If you need broader Rust fundamentals, you would start elsewhere.
Maintenance and License: What You Need to Know
The repository is not archived, and the default branch is `main`, but the README does not mention a release schedule or a versioning policy. The course content is tied to a specific set of chapters, and the README notes that the book's `SUMMARY.md` is the sole ordered chapter list, so any updates would likely be reflected there. The source code is licensed under Apache 2.0, which is permissive for use in your own projects. However, the mdBook text is licensed under CC BY-NC-SA 4.0, which is non-commercial and share-alike. That means you can use the text for learning, but you cannot commercially republish it without permission. The README does not describe an upgrade path for the starter code, so if you maintain a fork, you will have to merge changes manually. The course is a one-time learning investment, not a library you continuously update.
Editorial conclusion
Adopt this if you are a Rust developer who wants to learn how to design generic, type-erased interfaces for high-performance data processing, and you prefer a hands-on, test-driven course over reading theory. Do not adopt it if you need a production-ready expression engine or if you are new to Rust traits, enums, and references. Before starting, verify that you can run `cargo check -p type-exercise-starter --lib --locked` and that the chapter test workflow (`cargo x copy-test --chapter 1`) works in your environment. The course deliberately omits Decimal arithmetic, casts, and nested functions, so check the published chapter list to confirm the scope fits your learning goals.
Community notes