Can I do FP in my language?

Summary: We address the question directly, but then look deeper to the beliefs behind the question.

A very common question I get from experienced programmers is "What does an FP language give me that I don't already have? Can't I just do FP in my language?" This is a great question and I hope I have an equally great answer.

I really sympathize with this question. JavaScript has map, filter, and reduce. Java 8 has the stream library. It seems like every language is adding more and more functional features, including immutable data structures, first-class functions, function composition, destructuring, and sophisticated type systems.

And I agree: You can do Functional Programming in any language.

Functional Programming is just another paradigm. So just like you can do Procedural Programming in any language, or you can do Object Oriented Programming in any language, or Logic Programming in any language, you can do Functional Programming in any language.

But wait. That answers the question, but does it answer the deeper assumptions behind the question?

So let me ask you this: can I do OOP in C? According to my statement above, the answer is "yes". In fact, I've built small object systems in C before. So why would I need an OO language if I can do it in C? I feel like my object system gave me all of the advantages I needed to do OOP. But here's the thing: could I have programmed OOP in C without already knowing OOP? I don't think so.

These paradigms are called paradigms because they are wholistic perspectives about how to approach problems. OOP breaks problems into objects that communicate with messages. FP breaks problems down into data that represents the state of the process being modeled. Procedural breaks a problem into a series of steps that can solve the problem. Each paradigm has a different approach to solving problems. By "doing FP in Java" without already mastering FP, you're implying that FP isn't a paradigm, it's just a set of features (immutable data, pure functions, function composition, etc).

I've seen it many times. People say they're doing FP in JavaScript. What they mean is they sprinkle reduce and map around and they use some pure functions. There's a lot of value in that. But otherwise their code is procedural. They have not learned the paradigm, only the features.

The value of a language that strongly enforces a paradigm is that it immerses you in that approach to solving problems. The more it enforces the paradigm, the more you are forced to attempt solutions using that paradigm. The more functional your language, the more training you get in approaching problems in a functional way. The same goes for OOP and Procedural. In essence, you get more practice because you can't rely on the other paradigms you already know.

So let me say this, more controversial statement: outside of languages labeled functional (Clojure, Haskell, Elm, Scala, Erlang, etc.), I don't see much depth in the functional programming being done. Unless they're already familiar with functional programming by working for a long time in a functional language, programmers are borrowing only little bits of the FP paradigm and missing the best part, which is the change in perspective on approaching problems.

That's not to say it's not possible to learn real FP in JavaScript. But it will take lots of discipline and help. The language won't guide you. You'll need to guide yourself or find someone who will guide you.

Conclusions

All of the paradigms are great because a "point of view is worth 80 IQ points". You can do any paradigm in any language. But it is very hard to learn a paradigm without immersing yourself. And it's hard to immerse yourself in a paradigm without using a language that strongly encourages the paradigm. Until you do that, you might be borrowing features of the paradigm, but you're not approaching the problem in a new way. In short, Functional Programming is not a set of features. If you want to learn it, jump in the deep end and be immersed.