Haskellers have been isolating their side-effects from their pure code for decades, but most people write code in languages that allow ad hoc side-effects anywhere. In a lot of cases, these side-effects are practically a part of the public API -- they put restrictions the way the code can be used, often obscurely, and have effects that are observable to the caller. It helps a lot to acknowledge this and explicitly treat them as a part of your public API. Here are the basic ideas that I'll cover:
represent your side-effects as "intents to perform an action" -- transparent objects that expose the details of the side-effect, without actually performing it
combine effects with pure code to describe the execution order and data dependencies (yes, like a monad)
write unit tests for your code without mocking, by specifying the expected content, results, and order of side-effects performed by a function
I'll show a library implemented for Python, called Effect, that provides tools for doing this.
A lot of these ideas are similar to the Extensible Effects system described for Haskell, and I'll describe some ideas and techniques that even most Haskellers could use to make their code more easily testable.
Christopher Armstrong is a long-time writer of Python code, who recently immersed himself in the world of purely functional programming. He is a long-time contributor to the Twisted networking framework, and more recently has been working on the Effect library. He is also a budding Haskell enthusiast.
What’s the single most important design guideline for the creation of high-quality software? For Scott Meyers, it’s all about interface design. That includes user interfaces, of course, but also APIs, i.e., class interfaces, function interfaces, template interfaces, etc. The guideline is simple: make interfaces easy to use correctly and hard ...