Using types effectively
What if you could catch a bunch of bugs before your code even runs? In this article, Edvard Majakari, rocket scientist #20, shows how using the type system – especially with the help of phantom types – can prevent entire categories of errors. Bonus: there’s a dungeon crawler involved.
Read the full article on Ed’s GitHub.
In this article, we’ll explore practical ways to leverage static typing. Starting from basic union types to more refined concepts like Algebraic Data Types (ADTs) and finally Phantom types. To keep things a bit more interesting, we’ll apply these ideas to a fantasy-themed dungeon crawler RPG setting, illustrating how thoughtful domain modeling can neatly sidestep entire classes of bugs.
The core idea here is straightforward yet powerful: making invalid states unrepresentable by just using type system. This clever strategy helps us catch numerous errors at compile-time (or, in Python’s case, during type analysis), significantly reducing the likelihood of bugs that might otherwise inconvenience end users.
While this principle shines brightest in compiled languages, excellent work accomplished by mypy developers can bring us most of the same benefits. Rather than just preventing trivial mistakes (like letters sneaking into postal codes), a well-structured type system can express complex, logical transitions without adding any runtime overhead. Done right, this approach doesn’t just prevent errors; it also makes code easier to read and maintain. It is also worth emphasizing that the type system described here is implemented by mypy
, not Python itself.
Additionally, it can reduce or entirely eliminate certain forms of errors. If a condition simply cannot occur according to your types, there’s no need to test for it explicitly.