I really hate Cards Against Humanity.
I don’t particularly hate it for the obvious reasons of middle class white kids sitting around a table giggling at how transgressive they are being with their jokes about race. I don’t approve, and I would probably avoid it for that reason alone, but it’s frankly so banal in this regard that it probably wouldn’t be enough to raise my ire above lukewarm.
What I really hate about it is that it’s a game about convincing yourself that you’re much funnier than you actually are.
Cards Against Humanity is funny, but it’s not that funny. It relies on shock value to inflate its humour, and by making a game of that it draws you in and makes you complicit. Your joke about Vladimir Putin and Altar Boys? Not actually very funny, but by giving you permission to be shocking, Cards Against Humanity lets you feel like the world’s best comedian for an hour.
There’s nothing intrinsically wrong with enjoying pretending you’re funnier than you actually are. I’ve intensely enjoyed games where I got to spend an hour pretending I was an elf, and no harm was done to any parties involved (except for some imaginary orcs who found themselves full of imaginary lightning bolts). The difference is, I don’t walk away from the latter with any doubt in my head about whether I’m an elf (I’m not, in case you were wondering). People walk away from a game of Cards Against Humanity thinking that they’re hilarious.
Is this objectively a problem? I’m not sure I’d go that far. It would require too much of a digression into systems of ethics and theories of value.
Personally though, I hate it. I hate it a lot. Humour and accurate self-knowledge are both things I value, and the intersection is especially important because inaccurate self-knowledge about something you want to become better at is a great way of becoming worse at it instead. If you learn the lesson that being crass is a great way to be hilarious, you won’t become better at humour, you’ll just become better at being crass.
Which brings me to Ruby and Haskell.
These two programming languages are about as far away from each other on the field of programming languages as you can get. But one thing they have in common, other than garbage collection and list syntax, is their similarity to Cards Against Humanity.
Oh, they generally don’t give you the same sense of being way funnier than you actually are (_why’s poignant guide and learn you a Haskell aside), but they do have community norms that have similar effects of inflating your sense of how good you are at something important.
A thing I value probably at least as much as humour is good API design. It’s an essential weapon in the war on shitty software. It’s almost completely absent in Ruby. There are some exceptions (Sequel and Sinatra for example), but by and large Ruby APIs seem almost actively designed to promote bad software.
Ruby is full of people who think they’re doing good API design, but they’re not. The problem is that in Ruby everyone is designing “DSLs”. The focus is on making the examples look pretty. I’m all for making examples look pretty, but when you focus on that to the exclusion of the underlying semantics, what you get is the Cards Against Humanity effect all over again. You’re not doing good API design – you’re doing something that has the appearance of good API design, but is in reality horrifically non-modular and will break in catastrophic ways the first time something unexpected happens, but the lovely syntax lets you pat yourself on the back and tell yourself what a good API designer you are.
And then there’s Haskell.
The way this problem manifests in Haskell is in how incredibly clever it makes you feel to get something done in it. Haskell is different enough from most languages that everything feels like an achievement when writing it. “Look, I used a monad! And defined my own type class for custom folding of data! Isn’t that amazing?“. “What does it do?” “It’s a CRUD app”.
To a degree I’m sure this passes once you’re more familiar with the language and are using it for real things (although for some people familiarity just spurs them on to even greater heights), but a large enough subset of the Haskell community never reaches that stage and just continues to delight in how clever they are for writing Haskell. In the same way that Cards Against Humanity gives you a false sense of being funny, and Ruby gives you a false sense of designing good APIs, Haskell gives you a false sense of solving important problems because it gives you all these exciting problems to solve that have nothing to do with what you’re actually trying to achieve.
I very much do not hate Haskell or Ruby in the same way that I hate Cards Against Humanity, because unlike Cards Against Humanity these features are not the point of the languages, and the languages have myriad virtues to counteract them.
But I do find a fairly large subset of their communities really annoying in how much they exemplify this behaviour. They’re too caught up in congratulating themselves on how good they are at something to notice that they’re terrible at it, and it makes for some extremely frustrating interactions.
Cards Against Humanity is a drinking game. I’ve never seen it played sober. Everybody thinks they’re amazing at everything when they’re drunk, even though they know deep down that they’re not. This is not unique to this card game.
Come to think of it, all the Ruby companies I’ve worked at had big drinking cultures, too. Maybe Ruby is a drinking game that got out of control.
FWIW, I’ve regularly seen CAH played sober or mostly sober.
I can buy the ruby theory though.
I should try programming in Haskell while I’m drunk, maybe I’ll blow some peoples’ minds.
I have actually done this, but my general impression is that my drunk coding is not actually massively worse than my sober coding, and this remained true in Haskell.
I’m not sure what this says about my sober coding but it’s probably not good
I definitely get what you’re saying about Haskell culture, and at times I’ve found myself getting irritated about the same sort of thing. But here’s another way of looking at things that perhaps you’ll find less irritating. :) Very few people get paid to do Haskell, or get to use it for serious projects. Many of the people using it are using it for fun, to play around with different ways of writing programs, to learn, etc. From this perspective, it makes more sense that someone will be excited “hey I used a monad!”, because for them, this is a learning experience. With time and experience, people develop a better sense of when to use all these techniques, and it’s no longer “hey, I used a monad!”, it’s “using monads here makes the most sense, because…” I have noticed this from talking to people who use Haskell more seriously, they don’t generally get excited to use some technique for its own sake, they use what is the right for the job. (Don’t confuse this with the excitement at having a clean, elegant solution to a problem, which happens to use some technique because it genuinely is the right tool.)
Another thing that might explain some of this is that Haskell has kind of a ‘research culture’. People are always exploring new ways of expressing programs, and you probably see more of this if you read Haskell-related blogs and whatnot, because it’s more interesting to write about compared to posts about how you applied a well-known technique for the umpteenth time to some problem and it worked great… again. Not everything that gets explored is going to be super useful, and you sometimes see people applying techniques when they are overkill (this problem is definitely not unique to Haskell, it’s all over the tech world). But if you never try out new ways of expressing programs, you never get to the point of being able to make a reasoned decision to use one approach or another, and I think in the long run you are less productive!
> Haskell gives you a false sense of solving important problems because it gives you all these exciting problems to solve that have nothing to do with what you’re actually trying to achieve.
I think you are overstating here. Haskell forces you to program without side effects, and yes that requires learning lots of things. But there are many benefits to following this discipline, and with experience expressing programs without side effects becomes effortless, just like becoming fluent in a foreign language. It’s not true that the difficulties one encounters writing programs without side effects have “nothing to do with what you’re trying to achieve”, these “problems” are the consequence of learning how to express yourself in what is effectively a new language. The right way to think of these things are as investments in your future fluency. Even if you could do something quicker using techniques already known to you, you can still be justified in taking extra time to try something less familiar to you, since you’ll then know more and will be able to apply what you’ve learned more easily in the future. Short-term productivity on the immediate task isn’t the sole metric. If you want to make the argument that none of these investments pay off and you’re better off just doing things the way you already know, and anything else is a waste of time, well, you can try to make that argument, but don’t tacitly assume it.
Another way of looking at this is suppose the tables were turned and a person learned Haskell as their first language, then learned Python. That person might also say that they have to solve problems that have “nothing to do with what they are trying achieve”. (“How do I deal with the problems caused by type errors not being caught at compile time??”) Are they wrong in saying so?
Amazing, I’ve never seen a post before where every single word felt like something I could have wrote myself. ALL these things have annoyed me at various points. Great post, now to subscribe and read your other posts.
Pingback: On Cards Against Humanity | Mess of Cords