Functional Programming doesn't need a Functional Language

A crowbar is meant for prying ... but that didn't stop Gordon Freeman.

If you've ever been new to programming, you've probably spent a lot of time overthinking which language you should learn or use for a project. Honestly, this doesn't change a whole lot with experience — your considerations change, but the question inevitably comes up with every new project.

Recently, there's been an industry-wide movement toward adopting Functional Programming paradigms. And why wouldn't there be? There's a lot to love about Functional Programming! Given its status as "The New Hotness," a lot of engineers have been asking the question of what constitutes "real" Functional Programming; and every once in a while, someone says something like this:

That's not real Functional Programming. You're using an Imperative Language.

On its face, that sounds like a pretty sound criticism, right? It's certainly enough to dishearten some aspiring engineers who have just found out that they've just been booted from the cool kid's table and have to eat lunch with the rest of the imperative programmers.

What people who say this don't understand, though, is that programming paradigms are just models for how to build a program. Just because your language of choice wasn't specifically built for a particular paradigm doesn't necessarily mean that you shouldn't use it that way anyway. A crowbar is meant for prying, after all, but that didn't stop Gordon Freeman.

Functional Programming (FP) and Imperative Programming (IP) are just different approaches, and a language doesn't need to be a functional language to support functional programming.

The Razor

If you are interested in a razor to differentiate imperative and functional languages, though, loops are a pretty solid place to start. The idiomatic way to loop through an array in Imperative Programming is to do it in-place:

for x in [ 1, 2, 3, 4, 5 ] {
x; // each value
}

The idiomatic way to iterate through an array in FP is with a function that looks more like this:

each([1, 2, 3, 4, 5], fn(x) {
x; // each value
});

The imperative approach redefines the variable x several times within the same scope, which is fine for imperative approaches but a cardinal sin in functional ones. In the functional approach, x is never reassigned. It's a new x for every iteration.

Of course, this only proves that a language is capable of using a functional programming paradigm. The real test is in how you would build the each function. If you have to use a loop, then you are in an Imperative language. If you are in a functional language, you can use recursion:

fn each(arr , handle) {
fn _get(i) {
if (i < arr.len) {
handle(arr[i]);
_get(i + 1);
}
}
_get(0);
}

This approach is even better if you can do this with a built-in function.

The Result

As you have probably guessed by now, you absolutely can use functional programming in imperative languages. Whether a language is functional or not doesn't really matter much. That is, unless a language absolutely forbids a particular paradigm. Somewhat ironically, Haskell — the quintessential example of functional programming — explicitly forbids the Imperative Programming paradigm. There is nothing you can do to enable it, either. You must use recursions and built-ins.

What you really get from "pure" Functional Languages is a compiler that has been optimized for the Functional Programming approach. You don't need to worry about the cost of all of the indirections because the compiler will take care of that for you. Even so, the benefit of FP is not its speed — its correctness and expressiveness.

As Functional Programming continues to gain in popularity, languages will incorporate it into their standard libraries. As languages incorporate FP into their libraries, compilers will place greater emphasis on optimizing for this use-case. And as compilers optimize for FP, the costs of using FP in non-FP languages will fade.

So I wouldn't spend too much time worrying about whether my chosen programming language is purely functional or not. If Functional Programming is your cup of tea, and your chosen language doesn't block you from using FP principles, go ahead and do it. I know I will.