^{th}of February, 2012

# The Day Python Embarrassed Imperative Programming

This picture is like finding out that the Pope is not a Roman Catholic.

What you see there—click it for a much larger version^{[1]}—is the result of a very innocent question from a Python programmer to me, after he found out that I am a Haskell programmer. I will give you the lesson that I gave, of monads in Python, using that whiteboard.

The Python programmer said he had downloaded Haskell, and was experimenting with it. “But what is this monads stuff?” Never. Never *ever* ask that. One negative effect of asking that question is the horror of finding out that you use monads more than Haskell programmers; but because they are everywhere in your life, you have developed a blind spot to them. (Hint: do you use nullable objects?) In fact, as I showed him, every single object in Python is an instance of [the Haskell type class] Monad. So, to prove this ridiculous statement, I told him (upper-right corner): “Monads are conditional function calls.” So, every time you see a function being called inside an `if`

statement, you are looking down the howling void of a monad.

On the whiteboard, below that word “MONAD”, you can see the Python function, `pymon`

, whose definition is:

```
def pymon(f, v = None):
if v:
return f(v)
```

And with that in hand, I proceeded to explain.

In Haskell, one example of a monad is the `Maybe anythingElse`

type. It has two possible values: `Nothing`

and `Just anythingElse`

. In Python, every `object`

is an example of a monad. It has two possible values: `None`

and `anything_else`

. In both these cases, `anything_else`

can be any value. Right. So, every time you ever execute a function based on which of the two values is present, you have implemented the heart of `Monad`

. So, what makes it cool in Haskell is that this removes about six hundred and forty nine thousand two hundred and eighty-eight `if`

statements from your code. Much of your code is feebly re-implementing what `pymon`

is doing up there. If you could shove `pymon`

at every object, you would find that your code focuses on getting the job done, not baby-sitting `if`

statements.

On the whiteboard, I proceeded to implement `pymon`

in Haskell—as `hamon`

—which became what you see here:

```
hamon f v = v >>= f
```

So, you see that what increased the cyclomatic complexity of `pymon`

has been achieved in Haskell without any increase in cyclomatic complexity! That is a win, because if you can get away with conditional application of functions without littering your page with `if, if, if, if, if`

, you can implement large logic without fear, and in a terser, more-compact, well-manicured way.
The trick is that `>>=`

is the heart of the Monad, and we already implemented it up there in Python (as I will show).

I proceeded to say (on the whiteboard) that “`v >>= f`

” is this in a pseudo-code that looks like Python:

```
if v has something in it:
return f applied to what is in v
```

Which, the perceptive reader will notice, is *exactly* what `pymon`

says.

So I implemented `hamon2`

, which specialises `hamon`

to deal with one particular monad. (This is to basically show what `>>=`

is doing.)

```
hamon2 f (Just x) = Just (f x)
hamon2 f Nothing = Nothing
```

This obeys a rule about monads—followed in both Python and Haskell, whether we realise it or not (Python), and whether we like it or not (Haskell)—which is that a function that deals with a monad *at all* shall always return a monad. That is what is written to the middle-right of the whiteboard: “`>>=`

only ever returns monads”.
But the best thing here, of course, is that there is a simpler way, shown before, to implement `hamon2`

. And you can even make it more-general than `hamon2`

, such that it does not deal with just `Maybe a`

, but with any Monad. In Python, this is indeed the case, because every object is a monad already!

```
hamon3 = (>>=)
```

In English, the above line says: `hamon3`

is the longer name of `>>=`

.

But `hamon3`

is equivalent to `hamon2`

.

And `hamon2`

is equivalent to `hamon`

.

And `hamon`

is equivalent to `pymon`

.

And `pymon`

is equivalent to `>>=`

.

And `>>=`

is *the* heart of the Monad.

And so … you have been using monads in Python, all along sneering at the “smug Haskell douchebags who brag about the size of their gonads or something”. You are one of them. As my favourite bald-headed short man once said, “You who judge, do you not do the same things?”

So, both Haskell and Python use monads extensively; and Python does it *so much more* than Haskell. What, then, shall we say?

What makes Haskell’s take better is that it is simply *too* reusable. Do you know how it feels to write a complete JSON parser without having a single `if`

statement to handle failure (bad syntax), *and yet handling failure anyway*? I do. Have you ever checked a parser’s 200 lines of code and seen only three `if`

statements whereas every single function in the code handles a case of failure? I have. This is nothing spectacular, until you have to live without it—without pattern matching and such great abstraction as is provided by things like the Monad. The trick of that JSON parser is that no function even deals with any particular Monad—it just deals with any monad: “anything of which we can say ‘if `v`

has something in it, return `f`

applied to what is in `v`

’,” which happens to be nearly anything more-complex than the byte.

Lists? They are monads. File handles? Monads. Database query results? Timer countdowns? Fuel tank status? Monads. Even simple, direct, applicable understanding of monads is a Monad: if you grok, apply. And yes, even parser results are monads.

Because it is simple, you can live without it. But because it is simple, it shows up everywhere; so it is good to have a solid and ready toolkit to save you from a swarm of the case. Learn you a monad for great good. It is the little things, brother. Do not go at the monads so that you can learn some clever move; it is a simple, mundane thing that Java programmers implement every six lines they write. Just go at the monads to stop being *that* bored/boring. Deal with real complexity; not

```
if(x == null) return null;
// Proceed and use x
```

As a parting *coup*, I gave the Python programmer a link to the JSON parser I built in Haskell, some years ago. My company uses Haskell, because we do not have much manpower. We do not get paid enough, so we take many contracts. We cannot afford QA teams, so we use a sadistic compiler. We cannot dedicate too much time to any particular project, so we prefer to learn dense idioms (which takes time upfront, and saves time later), rather than learn sparse idioms that take more time to implement every time and debug individually. We do not keep a project in live mode after we have handed it over, due to little manpower, so any bugs that we have to cure at our own cost must be caught in development. Now, if you have few programmers, then they should be very efficient, and the best place to optimise is the tools. To make a sufficiently-fast programmer faster—like a sprinter running on a conveyor belt—make him stop dealing with gratuitously-explicit `if`

statements for a start (this is what makes threads difficult, for example: too many `if`

s). Enter monads.

It was embarassing to find that the language that we thought had shielded us from the assaults of the impractical ivoritoweritis of Haskell was always an accomplice in making us expert at *implementing* these self-same things at which we laughed. I have known betrayal—I have seen it, I have stood at a whiteboard and denounced it for what it was—and I took a picture of it.

[1] I use a Nokia N8. 12 megapixel camera. Terrifyingly-huge images. I love it.