The functional language that’s right under your nose

Published: October 11, 2006. Filed under: JavaScript, Programming.

Recently I’ve been getting an itch to learn a functional programming language. I’ve made a couple attempts on Lisp over the years, with mixed results; I can write fairly basic Common Lisp, and hack on Emacs a bit, but I’ve never advanced much beyond that. I’d been looking at some of the trendy, popular functional languages (well, popular among certain circles) like Haskell, OCaml and Erlang, when I remembered that I already knew a functional language. In fact, part of the reason why I was hired at my current job was to write in it. And, as I browsed through a discussion of functional languages on reddit, it was literally right under my nose.

Yup, I’m talking about JavaScript.

Digression: stupid things people say about languages

Programming languages tend to be a bit like religions: people get attached to them, develop unshakable faith in them and are all too willing to wish hellfire and damnation on heretics who won’t see the light. As a result, they tend to spew out misconceptions about other programming languages in much the same way that a Protestant fundamentalist goes around saying Catholics are idolaters.

For example, a lot of folks who aren’t card-carrying members of the Church of Python (blessed be Guido and all His works) like to go around saying that Python isn’t “really” an object-oriented programming language, because you have to use self.

Now, this argument really doesn’t make any sense; when defining a method on a class, the first parameter to it is self, and inside the method you reference attributes of the class instance you’re working with as self.this and self.that and so on and so forth. The reason behind this is simple: it explicitly establishes variable scope (think about it: take away the self, and you get things like foo = 3 — is that the attribute foo of the class instance, or is it a variable local to the method? Using self.foo = 3 for the former case and foo = 3 for the latter does away with the ambiguity). Plenty of other languages do this; for example, Java uses this and Ruby uses @. Nobody tries to argue that Java or Ruby aren’t “really” object-oriented because of that; Python goes a little further and requires you to explicitly list self as an argument to the method, but Python people like being explicit. If being explicit about scoping means Python isn’t really object-oriented, then being explicit about the types of variables and function return values means Java doesn’t really have a type system.

A lot of people will also say horrible things about JavaScript, because despite being a really interesting language, lots of people don’t like JavaScript (well, to be perfectly honest, lots of people don’t like the available implementations of JavaScript and, to be really honest, lots of people particularly don’t like the available implementations of one API that’s used a lot in JavaScript). For example, I’ve seen people try to argue that JavaScript isn’t “really” object-oriented because you don’t define classes using a class keyword. JavaScript uses prototype-based inheritance, rather than class-based inheritance, but it is still a thoroughly object-oriented language.

Anyway, the whole point of these examples is to show that lots of people say silly wrong things about programming languages all the time, and mostly it’s got more to do with some agenda they’re pushing than with anything remotely resembling reality.

One of the things people might tell you is that JavaScript isn’t a functional language. They’re right, but only for certain values of “functional”.

What makes functional programming?

If we want to be pedantic about it (and if you know me, you know I always want to be pedantic), there are a few things which characterize “pure” functional programming:

This kind of pure functional style has some definite advantages:

But a lot of this is academic; there aren’t a whole lot of pure functional languages, and when people talk about doing “functional programming” in real-world situations they’re rarely talking about pure functional programming. Common Lisp, for example, isn’t a pure functional language, even though Lisp is the patriarch of the functional language family. And OCaml, which is one of the darlings of the trendy functional programming world these days, also isn’t purely functional.

General mish-mash languages

Plenty of languages also support “multi-paradigm” programming; Python and Ruby, for example, both allow you to bounce around between procedural programming, object-oriented programming and functional programming, using each style wherever it best suits what you need to do. Generally these languages offer a few important features:

JavaScript has all three of these features: it supports closures, functions are first-class objects and you can define anonymous functions. This means that, in addition to doing procedural or object-oriented programming, you can easily do functional JavaScript programming.

The case for functional JavaScript

And there are a lot of times where you need JavaScript to be functional, even if you’re not used to thinking of it in those terms. Consider this example snippet of code, which — if you were using the YUI toolkit — would set up an event listener for clicks on an HTML element with an id of ‘myelem’:

YAHOO.util.Event.addListener(
    'myelem',
    'click',
    function(e){
        alert("You clicked the 'myelem' element.");
    });

This is obviously an extremely simple example, but notice three things:

  1. This is a function call.
  2. The final argument is a function.
  3. Not only is it a function, it’s an anonymous function.

If you’ve ever done any serious JavaScript programming, you were probably slinging functions — both named and anonymous — around all the time. Especially when you’re setting up event listeners or specifying more general callbacks, it’s just the most natural way to do things, but I’ve noticed that very few people, even people who write JavaScript day in and day out, realize that what they’re doing is a form of functional programming.

And that four-letter word that’s on everybody’s lips these days — you know the one I’m talking about — certainly encourages a functional programming style. For example, when making a remote call with the Dojo toolkit, a couple of the arguments to dojo.io.bind are functions, and a large number of useful examples use anonymous functions defined on the spot. YUI’s asyncRequest expects an object as one of its arguments, and several of the attributes of that object are, well, functions. Prototype’s Ajax.Request (damn, I had to say it; why’d they have to put “AJAX” in the name?) expects, among the other arguments to its constructor, an object, at least one of the attributes of which is a function.

And, of course, Prototype and JQuery are very heavily functional (JQuery, from what I’ve seen of it, much more so); very nearly everything you do with them is a direct function call, and lots of the functions you’re calling can take functions as arguments.

In other words, once you start looking for it, you’ll start seeing functional programming everywhere in JavaScript.

So?

You’re probably wondering if there’s a point to all of this, and I’m not sure there is. Based on what I’ve been seeing on a few noteworthy programming-oriented news sites, functional programming is enjoying a bit of a renaissance right now, and I know I’m not the only one with an itch to play around in a functional language. But that itch often takes the form of working with an entirely new language, requiring you to spend time not only learning the concepts, syntax and standard library, but also getting a development environment set up for it: an IDE, any compilers, interpreters or runtime environments for the language, standard libraries… just getting the tools you need to play with the language can be a major time sink.

But JavaScript doesn’t have that problem. Text editors which understand JavaScript are free and plentiful, and the standard library plus runtime is built in to your web browser. With certain browser extensions, you can even get a REPL-style playground. And, best of all, JavaScript is an extremely easy language to learn, and odds are good you already have some experience with it. So if you’re thinking of dabbling in functional programming but aren’t sure you want to commit to learning a new language and setting up its associated environment, give some consideration to JavaScript. You might be pleasantly surprised at what you find right under your nose.