&gt; I can pull it out into a static field. More importantly I can pass it back and forth through generic functions without them having to do anything special about it (e.g. as a database load callback), because it&#x27;s just a value. I notably can&#x27;t do this with exceptions (or e.g. if I&#x27;m emulating Writer with a global or ThreadLocal variable), though checked exceptions will at least fail this at compile time.<p>I understand, and as I said, I normally prefer not working this way. Others -- like yourself -- do. Both ways are perfectly valid. I prefer exceptions to <i>not</i> be values, as, to me, they capture a failed <i>computation</i> not a missing result. For a missing value, I can use null&#x2F;Optional etc.. But in any case, it&#x27;s not an either&#x2F;or thing. You can always catch exceptions and store them if you want; you can even use Either if that&#x27;s how you prefer to work.<p>&gt; If you&#x27;re willing to fix the order in which effects happen (and explicitly handle when you want to change it, as in your example) then you can write something much simpler than the usual monad transformers<p>How? You need to chain functions, each emitting some set of effects, and you don&#x27;t control in advance the order of the effects in each function.<p>I am not fixing the order of effects any more than in your examples. The reason the examples look different is because I&#x27;ve chosen to represent an error not as a value but as a control-flow construct, but I don&#x27;t have to, so let&#x27;s look at other effects:<p>If I have two functions,<p><pre><code>    void foo() { print(&quot;hi&quot;); log(1); } 
    void bar() { log(2); print(&quot;bye&quot;); }
</code></pre>
This is how I compose them:<p><pre><code>    foo(); bar();
</code></pre>
With monads you need to make sure that they both return the same nesting of Log[Writer] or Writer[Log], but I don&#x27;t need to care.