Rigidity is not the same as power

Dec 6, 2017

The debate in question is this: How powerful is your programming language?

Programmers love talking about this. And talking, and talking, and talking... To be honest, it gets annoying after a while. People have an almost religious connection to their favorite programming languages, and after a few times you get really, really tired of reading people screaming at each other on Reddit about whether Javascript or Python is better, whether Kotlin or Scala is better, whether Lisp is still relevant, whether F# or Haskell is better, better better better better better. It gets old. No, more than that, it's gotten old. It's been old since long before I got involved, and it's still old now. It's legitimately tiring, and it does. Not. Stop.

Please... Just stop...

I'm not here to preach one language over another. That's not how I work. I have no religious attachment to the languages I use - I prefer the languages I prefer for the reasons I prefer them, and that's that. It doesn't matter what other people think, unless they show me something that utterly changes my mind (something that hasn't happened very often, I might add).

What I am here to do is try to bring a little sanity to the discussion. To calm down the warring religions of ML style vs. Lisp style vs. OOP vs. FP vs. vs. vs. and so on with a little calm, well-reasoned, logical discussion. So that's what I'm going to do, starting with debunking a simple misconception (or trying to, at least).

Far too often, the debate about "How powerful is your programming language?" becomes a debate about "How rigid is your programming language?". This is a misconception that personally bugs me every time I see it, for one simple reason.

Rigidity is not the same as power, nor is it the opposite.

Advocates of compiled, statically-typed, highly-structured and opinionated languages like Java, Kotlin, F#, and Haskell will try to tell you that their rigidity is what makes them powerful, by preventing you from making mistakes you would otherwise make. Advocates of interpreted, dynamically-typed, unopinionated languages like Javascript, Python, Ruby, and Lisp (yes, Lisp) will try to tell you that their lack of rigidity is what makes them powerful, by getting out of your way and letting you really make the most of your code.

I'm here to tell you that they're both wrong, and that they're both right.

Stop, you're both wrong.

Rigidity is a useful tool. Restraint forces you to be more clever, finding ways to work within the constraints you're given. It also helps rule out some problems and bugs by making it harder to make mistakes. On the other hand, being less rigid allows for faster, more intuitive development, effective meta-programming, and a lot of simple solutions to difficult problems that simply can't be done easily in a more rigid language. Just as flexibility can be taken too far, so can rigidity, and both are good in moderation and bad in excess.

Far too often, people see rigidity as either entirely good or bad. They see a spectrum of programming languages, from most rigid to most flexible, and they pick a side that they see as "good" and decide that therefore the other side must be "bad". They come up with (legitimate) reasons for what they see as good and bad about them, ignoring the (also entirely legitimate) reasons to think the opposite, and they go off to war.

In reality, this just isn't true. The more I think about the languages I've used, the more I see the same spectrum, with one key difference. I haven't labeled one side as "good" and the other as "bad". I've simply labeled them as what they are, more rigid or more flexible.

Rigidity is good. Flexibility is good. Which you should choose depends entirely on what you're trying to do.

Do you want the ability to bend your programming language to nearly any imaginable style of programming and any possible purpose? You should pick a flexible language like Javascript or Ruby, that gets out of your way and lets you cross the streams as much as you want, with the full knowledge and acceptance that yes, you might get burned.

Sometimes, you have to cross the streams.

Do you want your programming language to find your bugs for you, ripping out entire categories of problems in one fell swoop? You should choose a more rigid language such as Kotlin or F#, that holds you to strict, mathematically sound design principles and prevents you from making silly mistakes like not checking for null.

Funny internet images aside, both of these are beautiful choices with their own ups and downs. Rigid languages like Java, Scala, C++, and so on often have trouble dealing with the possibility that something could be multiple types of things. Their rigidity is their greatest strength, but also their greatest downfall (and one of the reasons for "Nobody uses Haskell" being a flat out meme).

One does not simply use Haskell.

On the other hand, flexible languages have the same problem! Their flexibility is both their strength and their downfall - they let you do amazing things with the ease of no restrictions, but they're a double-edged blade that will bite you if you're not careful to reign in their flexibility to controllable levels. This is the reason that Javascript is considered such a mess - it's flexibility goes almost too far, to the point of being barely-comprehensible quirkiness (you might check out wtfjs if you're not sure what I'm talking about).

WTF, Javascript...

I know my half-coherent rambling isn't going to stop the language wars raging across the internet. Hopefully, though, it'll do some good to the people who read it. I guess all I'm trying to say is that programming languages are tools designed to fulfill a purpose. There's no point getting dogmatic about which is better, especially on a non-issue like rigidity. There's two sides to every coin - it's time we stopped acting like our grass is the greenest and realized that everyone has different needs, preferences, desires, and so on. Everyone has their own list of things they need from their programming language - there is no silver bullet.

It's time we stopped the crusading. Time to wake up and smell the coffee, and realize that it doesn't matter whether you prefer Javascript or Java, Ruby or Crystal, Python or Kotlin, functional or object-oriented, compiled or interpreted, rigid or flexible. At the end of the day, we're all developers - let's stop tearing each other apart over our differences and start building each other up in our similarities.