Functional JavaScript for Lazy Developers (Like Me)
By: M. David Green
Tags: JavaScript, Functional Programming, Web, Developer, Web Development

Functional JavaScript, a Remedy for the Lazy

One of the core concepts that has driven my quest for knowledge about programming techniques has always been my own laziness. After all, what attracted me to computers back when I first started playing with them was the notion that they could do things for me. All I had to do was sit back and tell them what I wanted.

But I quickly learned that computers were very literal. Unless I told them exactly what I expected in explicit and unambiguous terms, using a language that they understood, they would rarely give me back what I had in mind. And being lazy, I didn’t want to work any harder than I had to, to express my intentions.

I had then seen JavaScript go from a few imperative one-liners to large and convoluted object-oriented applications, and there seemed to be no end in sight to the complexity.

I started to look for ways to make coding easier and more fun. And that search led me directly to functional programming.

New Ways to Look at Problems

I was first introduced to functional programming when I was a senior front-end engineer working at a small start-up in San Francisco. One day, a programming wizard who labored deep in the bowels of the company’s research group heard me complaining about some of the messy state-dependent code I was working on, and lured me into a conference room with fancy promises. There, he proceeded to give me an impromptu three-hour introduction to Haskell, a classic functional programming language, including a cursory explanation of the philosophy of functional programming.

He mystified me with tales of functors and monads as I watched variables disappear, and methods split apart and merge together under unfamiliar type signatures. At the time it all seemed like strange sorcery, but he reassured me that JavaScript also had functional capabilities and that they would lead me to salvation.

That promise kept me going as I started to dig into this exotic realm. I believed that functional programming techniques could offer me better ways to break a problem apart and solve it in tiny, focused bites. I was thrilled by the possibility that I could make my code cleaner, more portable, more manageable, more readable, and easier to maintain.

All along the way, I discovered some wondrous things about functional programming in JavaScript, which I’ll delve into today.

Higher Order Functions

One of the things that makes JavaScript capable of handling functional programming techniques is the fact that it supports higher-order functions. Functions are treated as first-class citizens in JavaScript. That means that a function can take other functions as parameters, and can return a function as a result. Since that’s built directly into JavaScript at a fundamental level, the syntax is already familiar.

Using higher-order functions is the first step toward thinking about your code as a set of independent single-task components that can be taken apart and put back together in different ways to solve different problems. A function can easily be written to call any other function just by passing it in and then calling it during execution, optionally returning a new function to be called again at a later time. Since functions are passed by reference, they carry their context with them in closures, so they can operate within the state that existed at the time they were called rather than relying on the shifting possibilities of an external state.

Pure Functions with No Side Effects

Functional programming also brings with it some strong opinions about how functions should be written. A pure function in functional programming is the ideal. Pure functions don’t interact with any variables that exist outside of themselves. They don’t make any changes to variables not defined in their own scope, and they don’t rely on external values other than those passed in as parameters.

Pure functions always return the same result when given the exact same set of inputs, making it easier to create robust and reliable tests. That means that you can count on the result from a function staying the same as long as the parameters you pass in are the same. That also allows you to do some optimizations such as memoization, avoiding complex calculations by storing results in an array inside of a function and checking against that array before doing the calculations when a new input comes in.

Composition and Decomposition

As you start building your program out of pure functions, the patterns you’ll find yourself creating will have more to do with how you build up complex operations using simple interchangeable pieces. Because of JavaScript’s ability to take advantage of higher order functions, a small library of focused pure functions specific to the tasks they are trying to accomplish can be composed together as needed to perform highly sophisticated operations.

Another advantage of pure functions is that they perform one task and return one result. With careful naming, these pure functions become almost self-documenting. And the more you build your code out of independent single-task functions, the less deeply nested complexity you need to maintain and document. Your challenge becomes thinking about how to break your problem into small bite-sized pieces, and then compose them together in sensible ways.

Fitting Into Existing JavaScript

As JavaScript has evolved from simple one-liners in browsers into a sophisticated ecosystem for maintaining applications, the syntax of the language has evolved as well. With ECMAScript 5, arrays became functors, natively supporting a Map method for applying a function across every element of the array and returning a new array. Arrays also now have native methods for functional techniques such as reducing and filtering.

Newer features in ECMAScript 2015 and beyond include the convenience of arrow functions that make it easier and more intuitive to write code with anonymous in-line functions. The destructuring and spread operators also make it easier to work with arrays that may contain an unknown number of elements at the time they’re called. And generators give us native access to some of the magic of lazy evaluation, just like our friends who use Haskell and Ruby have been doing for years.

Most importantly, I realized that functional techniques are only one way to solve problems. JavaScript offers many alternatives, and in some cases, an imperative or object-oriented approach makes more sense. Adding functional programming to my repertoire just expanded the range of possibilities I saw when I was posed with a problem. These days I don’t generally insist on functional techniques for all of my JavaScript code, but I usually find sprinkling in some functional fairy dust makes reasoning about every programming challenge more approachable.

A New Way to Learn Functional Programming

As I started applying functional techniques, I saw my programs, my problem-solving skills, and my relationships with my fellow engineers improve. My code was cleaner, more self-documenting, and easier to maintain and discuss. And I was doing less work and enjoying the process more.

Eventually, I wanted to share this focused, functional way of thinking with everybody I met. So I started writing articles for SitePoint about functional JavaScript, passing along some of the mysteries I was exposed to these many years ago in that tiny conference room. The popularity of these articles, lead to me creating a course in functional JavaScript, which I was excited to see released earlier this year. Happily, I watched as others eagerly began to learn functional techniques and apply them to their development practices with positive reviews.

I hope you go out and explore different programming techniques that work for you and your team. If you’re curious about the benefit in using functional techniques, instead of wondering, instead give the course a try, and let me know how it affects your code, your thought processes, and your professional relationships. It had significant impacts in not only my work but also my professional career. I think you’ll find that adding functional problem-solving to your programming stockpile isn’t just lazy, it’s also productive and fun.

Is Functional JavaScript Programming Worth It?

Become a developer who knows the difference between functional and imperative code.

Become a developer who can switch between Object-Oriented Programming and functional.

Recognize when it’s better to use on technique over the other.

Here’s how: I’ll show you with my functional programming course. Add recursion, composition, mapping, and more to your development tool belt to make your code easier to read and less repetitive.