# There Can Be Only One...IO Monad

Scala developers have more choices than ever to represent effectful computation. Broadly speaking, these choices are divided into three categories: *non-functional*, *mostly functional*, and *purely functional*.

The *non-functional* solutions focus on concurrency, and are difficult to use in functional programs because they violate referential transparency:

The *mostly functional* solutions have a core that can be used in functional programs, but they do expose features that aren’t purely functional.

In order of increasing purity:

Solutions in the *purely functional* category expose only purely functional interfaces, including Scalaz 8’s IO, which has no impure methods on `IO`

, no impure execution contexts (implicit or otherwise), and no side-effecting combinators.

There are lots of other designs in the wild at various stages of development and production usage.

While all these choices are no doubt confusing for Scala developers, I’m a big fan of competing solutions. They quickly explore the landscape of design alternatives. In the end, the “best” solutions end up winning, usually for several different and conflicting definitions of *best*.

While the competition is undoubtedly beneficial, I recently encountered what I consider to be a myth in the Scala community: that the proliferation of effect types is *necessary*, because unlike Haskell, Scala programs have needs that are *too diverse* to be met by a single `IO`

type.

Today, I’m going to debunk this myth once and for all.

## One IO per Program

It’s easy enough to show that for any given purely functional Scala program, it only makes sense to use a *single* effect monad.

The reason for this is that a purely functional program will necessarily be expressed as a single value of type `F[Unit]`

, where `F[_]`

is the effect monad of the program (such as `Future`

or `Task`

or `IO`

).

Conventionally, we call this value `main`

:

Purely functional programs are expressed in terms of *composition*. Smaller fragments are composed to form larger fragments. For example, if we have some fragment `F[A]`

, representing a computation producing some value `A`

, and another fragment `F[B]`

, then we can compose them in various ways to yield another fragment `F[C]`

, producing another value.

But if we have one fragment expressed as `F[A]`

, and another expressed as `G[B]`

, where both `F[_]`

and `G[_]`

are *different* effect monads, then we have a problem: they don’t compose! We can’t take a `Task`

and a `Future`

and compose them together, for example.

In order to compose two effect monads, we’d have to convert the `F[_]`

to the `G[_]`

, or the `G[_]`

to the `F[_]`

. But if we can convert from one to the other, we have proven the second is at least as powerful as the first, *so there is no reason to use both*. We only need the more powerful effect monad.

Using two different effect monads, and then converting from one to another, just increases overhead, because many more structures will be allocated and many more virtual methods will be invoked. So not only is there *no reason* to use two effect monads in the same program, but there are (performance) reasons to *not* do so!

This is why purely functional Scala programs have only *one* base effect type.

## One IO per Ecosystem

Hopefully by now, you’re convinced that any given Scala application needs only one effect monad such as `Task`

or `IO`

. However, you *might* still think that different applications might require *different* effect monads that provide fundamentally different feature sets.

For example, maybe Twitter’s “effect monad” needs cancelation, to avoid wasting network resources, so they have to use a different `Future`

than other applications.

This myth rests on the (false) premise that different types of applications require fundamentally distinct capabilities that cannot be provided in a single effect monad.

To dispel it, I will now present the *ultimate* `IO`

monad, which can provide *any capability* required by *any application* whatsoever.

Brace yourself for the overwhelming torrent of Scala code:

That wasn’t so bad, was it?

This `IO`

monad is defined in just 17 lines of extravagantly spacious code. It can do anything that *any* other effect monad in the entire Scala ecosystem can do!

To show this, it suffices to point out two facts:

- All other effect monads must be implemented in terms of the imperative subset of Scala programming (that is, there isn’t a
*different*language available to implement Scala effect monads; it’s just the same old Scala!). - All imperative subsets of Scala code can be encoded with the above
`IO`

monad.

The first point is obvious. The second point can be seen by showing how a generic snippet of imperative Scala can be translated into the above `IO`

monad.

Let’s say we have the following snippet of imperative Scala, which consists of imperative statements `v_1 = <e_1>`

to `v_n = <e_n>`

, each of which do impure, effectful computation by executing an arbitrary chunk of Scala code and storing the result in a variable:

In general, subsequent expressions will depend on variables introduced by prior expressions. For example, here’s a simple console program that demonstrates this sequential dependency:

Notice how the expression defining `v_3`

refers to `v_2`

. Now, if some expression `<e_i>`

evaluates to `Unit`

(such as the first expression above), its corresponding variable assignment in statement `v_i`

can be ignored.

With a little effort, you should be able to convince yourself that *all* imperative Scala code can be written in this form. In turn, any imperative snippet in this form can be translated into the above `IO`

as follows:

Of course, Scala provides `for`

comprehension syntax for code structured in this fashion (otherwise known as *do notation*), so we can write this as simply:

This structure captures *all the effects* of the original imperative snippet, which can be recovered by running the `unsafePerformIO()`

method on the final `IO`

value.

Some people have claimed that, for example, a synchronous `IO`

like this one doesn’t provide asynchronicity, so we need a `Future`

for asynchronous applications.

That’s completely false, as I’ve demonstrated here. In fact, for this particular myth, it’s useful to show a simple but powerful encoding for asynchronous effects (technically a specialization of the continuation monad `ContT`

).

We can define a wrapper for asynchronous `IO`

computations like so:

There you have it, an asynchronous monad in about 20 lines of code, built on the `IO`

monad previously introduced. It doesn’t matter *what* features you want to add to your effect monad, they can *all* be easily expressed in terms of the above `IO`

.

In other words, no effect monad, no matter who wrote it, and no matter what it does, is more expressive than the 17 LOC effect monad introduced in this post!

## Why Scalaz 8 IO?

Some may wonder if the 17 LOC monad I introduced in this post is as expressive as any other, why I am spending additional time developing Scalaz 8 IO.

The answer is simple: although the `IO`

monad introduced in this post is as *expressive* as any other, expressing features common to many Scala applications would introduce many additional allocations and virtual method invocations.

The `IO`

monad I’m developing for Scalaz 8 bakes in additional functionality, not because it’s necessary, but because doing so *greatly* increases performance.

Most Scala applications have to constantly deal with three real world concerns ignored by toy and pedagogical effect monads:

**Asynchronous Computation****Concurrent Computation****Resource Management**

By providing clean, composable, and built-in semantics for dealing with these real world concerns, Scalaz 8 `IO`

will provide the critical combination of performance, ease-of-use, and principled design necessary to succeed in a crowded marketplace of non-functional, semi-functional, prototype, and toy effect monads.

That’s the goal, anyway. The Scala community will decide if it’s successful.

## Summary

When it comes to modeling effectful computation, the Scala community has more choices than ever—from `Future`

monads baked into Scala, to `Task`

and `IO`

monads developed by the community, with varying degrees of purity and safeness.

While these competing solutions are useful to explore the landscape of possible designs, it’s critical to remember that programs only *need* one effect monad. More than that, because every effect monad is *as expressive* as any other, there’s no reason why we need more than *one* effect monad for the entire Scala community.

The only reason to specialize an `IO`

monad more than the toy example provided in this post is to improve performance. Real world concerns for nearly all Scala programs include asynchronicity, concurrency, and resource management, and in my opinion, the winning design in this space will provide *all three* in a performant, principled, and pure package.

In the Haskell world, there’s only one `IO`

monad, and there’s no need for anything else. Over time, we may find that whatever effect monad design ends up winning will become Scala’s one and only `IO`

monad.

At the end of the day, after all, there can be only one!