I often follow the functional core, imperative shell way of constructing software: Isolate business logic into a set of pure functions (the functional core). Implement side-effects and mutable state in a thin layer around the core (the imperative shell). This not only shapes how I write code, but also how I think. When designing a software system, I’ll assume the functional core and the imperative shell are independent. This allows me to ignore servers, storage, networks, and other technica...