Inside the Cult of the Haskell Programmer

It’s spooky. It’s esoteric. It’s also the key to understanding the rise and relevance of functional programming.
Image may contain Cinema Indoors Theater Clothing Hat Electronics Screen Person and Adult
ILLUSTRATION: SAMUEL TOMSON

In my first job out of college, I was assigned the task of rewriting the autocomplete feature of a search page. The original code, entombed in a decrepit codebase, was a nauseating monstrosity that others wanted no truck with. The plan was to rewrite it in TypeScript—a dialect of JavaScript—drawing on a library that incorporated some handy features from a language called Haskell.

Haskell. It sounded like a good name for a weapon—a well-sharpened blade, like scimitar or katana. The strong German-sounding plosive in its name, as in Nietzsche or Kafka, added a menacing edge. All I really knew about the language was that it was challenging and intended for math PhDs.

The rewrite could be done without knowing Haskell, technically, but I was an overeager graduate with a “challenge accepted” attitude to everything, even when it was absolutely uncalled for. I found a whimsically titled tutorial book—Learn You a Haskell for Great Good!—and spent that winter writing Haskell most evenings after work. It was like learning to program all over again.

Long before Haskell coalesced into a programming language, it was a swarm of theoretical concepts. In 1977, the computer scientist John Backus delivered an influential lecture titled “Can Programming Be Liberated From the Von Neumann Style?” In it, he argued that existing languages were becoming bloated and ineffective. It was a clarion call to evolve “functional programming” from mathematical esoterica to a practical tool.

Programming paradigms are mainly divided into “imperative programming” and “functional programming.” The dichotomy isn’t clear-cut, as a growing number of languages support both styles, but for our purposes it may be enough to say that in imperative programming you write code as a series of steps, line by line, while in functional programming you define mathematical functions and let the machine worry about the steps. In terms of actual functionality and usage, imperative programming is the far more common approach.

Before Haskell, academic researchers had implemented certain functional concepts in the languages they worked with. But in the late 1980s, a group of computer scientists came together to smelt them into a single language. They named it after the logician-mathematician Haskell Curry, whose work is foundational to programming language theory. (The original plan was to name it Curry, but the group soon realized—a bullet dodged—that this would make it vulnerable to bad culinary puns.) The Haskell committee would blowtorch the messy excess of imperative programming with high-powered mathematics, sculpt a new chassis with the guidance of advanced logic, and weld everything together with modern compiling techniques. Out of the scalding forge, Haskell 1.0 was born.

Haskell simply looked different from anything I’d ever seen. Spooky symbols (>>=, <$>, :<:, <|>) proliferated. The syntax was almost offensively terse. The code for the Fibonacci sequence, which can span multiple lines in other languages, can be written as a one-liner shorter than most sentences in this article: fibs = 0 : 1 : zipWith (+) fibs (tail fibs). You might as well sign off each Haskell program with “QED.”

Whenever I set out to learn a new language, the first small program I try to write is a JSON parser, which converts a data format commonly used for web applications into a structure that can be manipulated by the computer. Whereas the parser I remembered writing in C had resulted in a programmatic grotesquerie spanning a thousand-plus lines, I felt a frisson of pleasure when Haskell allowed me to achieve it in under a hundred.

At the same time, I understood almost immediately why Haskell was—and still is—considered a language more admired than used. Even one of its most basic concepts, that of the “monad,” has spawned a cottage industry of explainers, analogies, and videos. A notoriously unhelpful explanation, famous enough to be autocompleted by Google, goes: “A monad is just a monoid in the category of endofunctors.”

The language is also more despised than explored. Steve Yegge, a popular curmudgeon blogger of yesteryear, once wrote a satirical post about how, at long last, the Haskell community had managed to find the one “industry programmer who gives a shit about Haskell.” For programmers like Yegge, Haskell is a byword for a kind of overintellectualized, impractical language with little industry applicability.

What Yegge didn’t understand, however, is that using Haskell is rarely a pragmatic decision. It is an intellectual, even aesthetic, one. In its essence, Haskell has more in common with the films of Charlie Kaufman than other programming languages: highly cerebral, charmingly offbeat, and oddly tasteful; appreciated by those in the know and judged by outsiders as pretentious. Haskell is, one might say, a cult classic.

That Haskell never gained widespread adoption exemplifies a paradoxical truth in software engineering: Great programming languages aren’t always great for programming.

Haskell is not inherently more difficult to learn than something like C, but the two languages pose different challenges. Writing in C is akin to precision engineering, requiring the kind of attention demanded of a skilled horologist. But Haskell code is, really, code-shaped mathematical expressions. C is a quintessential engineer’s language. Haskell is a pure mathematician’s.

A good engineer’s and a good mathematician’s aptitudes don’t always overlap. The industry’s not-so-well-kept secret is that most programmers aren’t as good at math or logic as you might think. This is mostly fine. After all, many doctors would make poor molecular biologists, few lawyers are legal philosophers, and the great majority of MBAs know zilch about econometrics. But this means few programmers can really master Haskell. This includes me, of course, whose legs weaken at the sight of such expressions as “F-coalgebra” and “typeclass metaprogramming.”

Still, when I think about Haskell, a line about Martin Amis’ prose comes to mind: “the primacy he gives to style over matter.” Haskell programmers are style supremacists, and it’s nothing to apologize for. In an industry often fixated on utility and expediency, the Haskell community should not feel obligated to summon evidence of its usefulness. Instead, it should simply retort: What’s the problem with useless intellectual exercises?

Because the thing about useless exercises is they don’t stay useless for long. Even when “industry programmers” shunned Haskell, language designers took note. In recent years, a Haskell-style paradigm has come into vogue because of the treasury of benefits it offers: rendering certain categories of bugs impossible by design, making a program’s correctness more provable, and enabling easy parallel computation. Some of the most anticipated updates featured in new versions of imperative languages are those inspired by functional programming. In the end, Backus’ anti–von Neumann plea was heard. Programming has been liberated.