Improving your functional CoffeeScript and JavaScript

Lately I have found myself being influenced by functional programming languages like Haskell and Clojure, especially in how I write JavaScript. Despite it still being a bit verbose, I think functional JavaScript can be very elegant. Add CoffeeScript to the mix and it’s looks even better.

More importantly, I find that code written in a functional style is much simpler than imperative code. It is easier to test, reuse and rewrite. So how do you do this in JavaScript?

One way to get started is to use something like Underscore.js and convert those good ol’ for loops to compositions of higher-order functions. I think the following example, although rather simple, shows how functional style code can be much easier to read and understand.

If you are not used to this style of writing and want to learn more, I would recommend studying a functional language like Haskell or Clojure where higher-order functions are pretty much the bread and butter.

Trying to improve my functional JavaScript and CoffeeScript I started looking at monads. I really like Haskell’s do notation so I thought that I could try implementing my own version in CoffeeScript. The goal is both to implement a do notation and to write the implementation itself in a functional style. The following is my attempt at doing so.

So, what’s a monad?

I’d like to point out that this is not a monad tutorial. There are vast amounts of tutorials on monads already, and I will try not to contribute to the monad tutorial fallacy. However, I think that some kind of summary is needed for the purposes of this post.

“In functional programming, a monad is a structure that represents computations defined as sequences of steps.”

Monad (functional programming), Wikipedia

The core functions of a monad is return (also called unit) and bind (>>= in Haskell).

  • return takes a non-monadic value and returns a monadic value.
  • bind takes a monadic value and a function which is applied to the non-monadic value.

In Haskell, these are defined as follows. Note that this is not the actual Monad typeclass.

In other words, a monad defines how monadic values are constructed and how a computation is applied to those values.

Monad Definitions

To represent the monad I use a simple JavaScript object containing the return and bind functions.

Maybe

I use two container types for the Maybe monad – Nothing and Just.

… along with these convenience functions.

The definitions looks like this.

Given this definition, I can bind computations to monadic values as follows.

Promise

Using the excellent Q library, the Promise monad is even simpler to define.

Using the underlying promise functions of Q is more straight forward than using the monad, but we will need the abstraction later on.

Implementing the do notation

Haskell’s do notation supports a number of forms. To keep my version simple, I decided to implement only the <- binding. <- takes a monadic value and binds the non-monadic value to the given symbol. In Haskell, the following expressions are equivalent.

The steps of the do expression is translated into a chain of monad bind operations.

To mimic this in CoffeeScript, I need some way for computations to refer to the non-monadic values of preceding computations (e.g. for the last computation in the Haskell example to refer to five and two). The best thing I’ve come up with so far is recursively building a scope object to which the computation functions are bound. This enables each computation to refer to non-monadic values through this.

Actually, I started out with a single scope object which was mutated in each recursion. I even used indices in the recursive function calls. In short, an ugly mess!

Later on when looking back at the implementation I realized I should create new scope objects and get rid of the indices. It is really just a fold of the computations, although slightly more complex because of bind.

Trying it out with Maybe

The equivalent code in JavaScript does not look too bad.

Promises in action

This is a bit more interesting example using promises.

Summary

Writing the do notation in CoffeeScript was very fun! For me this was also a great way to learn more about CoffeeScript as well as monads. Even if I’ll never write anything useful in Haskell itself I am sure it will remain a great source of inspiration for writing functional JavaScript and CoffeeScript.

If you are interested in functional JavaScript, give Haskell or Clojure a try, and see where it takes you. It’s a great learning experience, and a lot of fun!

This Post Has 2 Comments

  1. Nice post! Do you have any good resources for learning more about monads?

    1. Thank you Christian! The online book Learn You a Haskell for Great Good has a thorough chapter on monads. It has helped me a lot and I think the book is great for learning functional programming, even if you’re not using Haskell.

Leave a Reply

Close Menu