Pragmatism

by Michael Ruggiero

I’ve been thinking about pragmatism lately. Some thinkers that I respect, like Paul Chiusano and Tony Morris, have put forth the idea that pragmatism is a serious problem in software engineering. That we leverage our futures by taking a worse is better view. “Worse is better” gave us a mess; why can’t developers see that?

But I suspect that the difficulty of algebraic modeling is not the actual issue. I understand the case that Morris makes when he says that unalloyed pragmatism is “cynical.” He’s pointing to a developer culture that rejects FP on the grounds that “instead of thinking in terms of proofs, we’ll use our own experience to dictate next steps.” Because it’s pragmatic.

But I would argue that what is lacking is not good faith re: the value of mathematical proofs, but basic heuristics for why proofs would be something you’d want to employ in production code. We don’t have a lot of war stories in that regard. Recall Simon Peyton Jones’ talk “Haskell is Useless.” Now, of course Peyton Jones was not alleging that Haskell was useless, rather that, if you create a spectrum of purity-to-practicality, Haskell scores high in purity and low in practicality. It’s not a zero or a one. And, he argues, F# is an attempt to correct that imbalance.

Part of it is the fact that terms like “purity” and “correctness” are overloaded, and need some parsing to make them relevant in the context of corporate engineering culture. That culture has smart people who disagree. It doesn’t make me “cynical” to say “we could probably get this done faster in Python,” but it does make me cynical to say “correctness is not an issue because I don’t understand why it could be relevant.”

Which is not to say that FP has a marketing problem… except that it does have a marketing problem. The only reason that people take Scala and Haskell seriously now is that it solves problems of parallelism and concurrency in a way that few languages can. But if those problems didn’t exist, we would likely continue to consign FP languages to the column of “academic” (a term whose second definition is not of practical relevance; of only theoretical interest).

And the code itself does not lend itself to the sort of “I found the answer on Stack Overflow” kind of learning. For instance:

def traverseS[S,A,B](fa: F[A])(f: A => State[S, B]): State[S, F[B]] = 
    traverse[({type f[x] = State[S,x]})#f,A,B](fa)(f)(Monad.stateMonad)

OK, it’s easy to grab some piece of inscrutable Scala and use it to prop up an argument (in this case it’s p. 221 of Chuisano & Bjarnason). But I mean it by way of illustrating the challenge that FP presents to conventional corporate programming. What problem is that code snippet solving? Obviously, I removed all the context but you have to admit, that’s some really ugly code.

So you can’t make the case that correctness is somehow self-evident. If it were, everyone would share your conviction: you’d have an existence proof in your favor.

I imagine that some of us writing code in the corporate world would prefer not to be lectured on our collective stupidity. Instead, we’d love narratives. War stories. How many developer hours were saved? How quickly was a production library crafted, how low was the number of production defects? Selling.

I’m remembering one day, I was sick at home, watching “Testing the Hard Stuff and Staying Sane” by John Hughes. (It’s great: go watch it.) I was a longtime TDD practitioner, and I watched Hughes advocate FP and property checking as something that made tangible, real-life, pragmatic difference in the testability of code. What’s wrong with that? Also known as: selling. John Hughes completely sold me.

There’s nothing wrong with selling. Frank Zappa once said: “Art is making something out of nothing and selling it.” And I sort of agree.