By either making the data const, or encapsulating mutable state with private fields and public methods
> How can you do "Errors as values"
Go, Rust, Odin, Zig, and many more are imperative languages that do exactly this
> How can you do "Functional core, imperative shell"
Write a function that takes the old state and returns the new state