#readwise
# This Is Not a Monad Tutorial

## Metadata
- Author: [[John Azariah]]
- Full Title: This Is Not a Monad Tutorial
- URL: https://johnazariah.github.io/2022/12/06/this-is-not-a-monad-tutorial.html
## Highlights
If we do this for the whole happy path, we get something like this:
```fsharp
ErrorChecked<Client, Error> client(RemoteHost host) =>
config(host.Jumpbox.AuthConfig)
.CallWithValue(jbConfig =>
ssh.Dial("tcp", fmt.Sprintf("%s:%d", host.Jumpbox.URI, host.Jumpbox.Port), jbConfig)
.CallWithValue(jbConn =>
jbConn.Dial("tcp", fmt.Sprintf("%s:%d", host.URI, host.Port))
.CallWithValue(hostConn =>
config(host.AuthConfig)
.CallWithValue(hostConfig =>
ssh.NewClientConn(hostConn, host.URI, hostConfig)
.CallWithValue((ncc, chans, reqs) =>
ssh.NewClient(ncc, chans, reqs), nil)))));
```
Now, this looks like an abominable mess compared to what we started with. ... However, we’d be hard-pressed to call this a success, because we’ve kind of turned everything inside out, and taken a relatively neat sequence of instructions and converted it into this deeply-indented horror!
In fact, **this “deeply-indented horror” has a name: it is actually the program written in a form known as “Continuation Passing Style”, and as we will see later in this blog post, is a universally powerful way to express code.**
It turns out that **even a normal sequence of instructions - like the semi-colon separated sequence we’re familiar with - can be *mechanically* converted (de-sugared) into continuation passing style. Of course, we want to go the other way, and apply some form of syntactic sugar to convert this continuation passing style into something more palatable.**
This is where the language we’re working with makes a *big* difference. Functional languages like Scala, Haskell and F# have simple and easy ways to put a pleasant syntax on the continuation chain. C# *does* have a way to represent continuation chains around arbitrary wrappers as well. (`go`, on the other hand, unfortunately, does not - and one is cursed to write out the tedious `if err != nil` blocks by hand.)
At a naive level, this is what we stated the problem to be:
We want to consistently error-check the results of functions called in a sequence of instructions, but we don’t want it to compete for attention from the focus of what this sequence is doing.
A slightly more insightful - and perhaps a little more abstract - level, what we really wanted was:
**We want a way to sift out a boilerplate pattern from the code and allow us to take the boilerplate as part of the context of executing a sequence of instructions.** ^fve4o6
Now, there are many approaches we could have taken to do this. Let’s summarize the one we took:
- **In order to force the caller of a function to treat the returned value in a way that forces the boilerplate to run, we chose to wrap all return values from a function in an opaque unbreakable box.**
- Since the returned value is opaque and unbreakable, one way to utilize the contained value is to invert control and package the rest of the instructions into a lambda, which we then pass to the opaque unbreakable box - allowing it to run any boilerplate and then call the lambda with the hidden value.
- **The lambda actually has no idea that it’s being executed in this special context.** This is a profound realization, which will lead to some interesting consequences.
- **We apply this inversion of control to the rest of the statements, and this results in a deeply nested chain of continuations.** We can also make some observations about this chain - the first of which is that **it’s tail-callable, which means it can run with constant stack space**. This shouldn’t come as any surprise because the initial sequence of instructions was also runnable with constant stack space.
- We then apply some syntactic sugar using the mechanics afforded by the language we’re using. ([View Highlight](https://read.readwise.io/read/01gmj5g5594s9tdtha4w6e6qyc))
---
**it’s easy to see that what we’re trying to solve is the problem of composing functions: not plain composition, but composition within a context. ... We had to do some work to get here, but in the end, that’s all we were doing - composing functions in context.**
---