202506201106 Make invalid states unrepresentable
As software engineers, we should strive to make our own lives and those of our fellow developers easier. By easier, I mean we should make it easier to make good software that works, is reliable, does not have bugs, performs the expected function, is verifiably correct, and is easy to maintain and extend. One way we can accomplish these goals is by making invalid states unrepresentable.
Making an invalid state unrepresentable means that we cannot actually express or build our system if it would result in an invalid outcome. We take advantage of our language's toolbox (types, classes, names, modules, and whatever else) to build constructs that cannot be used incorrectly.
For example, we can make a class or type that cannot be instantiated if it would be in an invalid state. A classic concrete example is a non-zero positive number.
;
This seems like extra work for representing something that we can easily use other number types (e.g., u64
) for, but the value comes from the knock-on effects of adding constraints that reduce our power.1 We know every time we have a NonZeroPositive
that it will necessarily be non-zero and positive. We don't ever have to check that constraint again and can use that type in ways that you couldn't use a possibly zero number (e.g. as a denominator) without introducing bugs or invalid states.
There are many ways to make invalid states unrepresentable:
- The newtype pattern234
- The typestate pattern5
- Pre- and post-condition assertions6
- Invariant assertions
- Constructors, setters, and getters
- Strong and/or static type systems
- Parsing instead of validating7
This is a massive topic, and this note isn't meant to be exhaustive. Instead this should be a jumping off point for more investigation.
-
Lou, C. (Director). (2016, June 5). Cheng Lou—On the Spectrum of Abstraction at react-europe 2016. https://www.youtube.com/watch?v=mVVNJKv9esE ↩
-
Kladov, A. (2018, June 4). Newtype Index Pattern. Matklad. https://matklad.github.io/2018/06/04/newtype-index-pattern.html ↩
-
Morrison, A. (2024, December 9). The Ultimate Guide to Rust Newtypes. How To Code It. https://www.howtocodeit.com/articles/ultimate-guide-rust-newtypes ↩
-
Drysdale, D. (2024). Effective Rust: 35 specific ways to improve your Rust code (First edition). O’Reilly Media, Incorporated. ↩
-
Biffle, C. (2019, June 5). The Typestate Pattern in Rust. Cliffle. https://cliffle.com/blog/rust-typestate/ ↩
-
Greef, J. (2022, May 23). Tiger Style. https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md ↩
-
King, A. (2019, November 5). Parse, don’t validate. https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/ ↩