When Rain mentioned recently they had a draft monad tutorial that explains them without mathematical jargon, with practical examples, and as a design pattern, I knew it was going to be good. Of course, it is even better than I hoped.
“Demystifying monads in Rust through property-based testing” is an undersell of a title. If you’ve floated around the world of functional programming long, you’ve probably seen one of the many attempts at explaining monads. Many are from the perspective of a formalism—the monad laws—and written with Haskell—the language that made them a central feature with syntactic sugar and a direct to how IO is done.
Rain instead introduces monads with a practical example of how their flexibility actually makes some work harder, motivated with a concrete example of how “shrinking,” a core operation for doing practical property-based testing, becomes much more difficult when monadic operations are used to generate test inputs. Instead of Haskell, the tutorial uses Rust.
Thanks Rain for the best monad tutorial I’ve ever read!
I really like Jack Wrenn’s new article “The Three Basic Rules of Safety Hygiene,” which covers how to handle unsafe code when you have to write it, through a hygiene checklist for expressing and validating compliance with safety conditions in the code.
Rust’s goal is not to eliminate unsafe code, but to contain it in isolated modules you can audit and which provide safe interaces to external users. Sometimes unsafety is necessary, and having a process for how to handle that unsafety is a key development.
Research on how to reduce things like industrial accidents, medical incidents, and airplane crashes all consistently find that checklists and procedures work. Humans are fallible, and being accountable to a checklist or a process defends against our propensity to make mistakes.
Amid the move to memory safe languages, the people who build and build on C and C++ ought to be recognized. Any of us could be hit by an upheaval of technology in which we’ve invested.
Rust types offer four ways to decide what happens next, along two axes: deciding at runtime vs. compile time, and permitting a closed or open set of types.
Rust generics can trade off binary size for expressiveness. Learning to identify when the trade isn’t worth it is a valuable skill that can help you write better code.