JavaScript is a multi-paradigm language, which means it supports object oriented, imperative and declarative programming styles. I wrote a previous article about how JavaScript’s support for first class functions (functions that can be passed as arguments like any other object) makes learning to program JavaScript in a functional style a good way to build your ability to reason about code.

In this article, I’m going to focus on the basic “primitives” of functional programming (FP), the concepts that will allow you to start thinking functionally — pure functions, currying, and composition.

From my research, I’ve generally seen FP defined two ways:

Theoretical:

Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions. -Stack Overflow

Practical:

Functional programming is about writing pure functions, about removing hidden inputs and outputs as far as we can, so that as much of our code as possible just describes a relationship between inputs and outputs. -A Jobbing Programmer’s Definition of Functional Programming

I’m going to focus on the practical application of FP concepts in this post. To learn the basics of how to apply FP to your programming, I’ve found that it’s not necessary to learn the theoretical aspects right away. For now, I’m going to focus on how FP contrasts with object oriented programming, the default paradigm for organizing code in JavaScript. Practically, we’ll learn how to write pure functions, how to partially apply arguments to pure functions (currying), and how to combine multiple pure functions as building blocks to make more complex functions (composition).

A Quick Contrast between OOP and FP

In object oriented programming (OOP), the structures storing your data are the focus of your programming. You spend most of your time thinking how to model your data using objects, and how to achieve code reuse by having your child objects inherit as many properties from their parent objects as possible.

An example:

In the example above, I spent quite a bit of time thinking about how to model my data. Which properties do I store in the parent class and which do I store in the child class? In this case, I chose to give the Parent class the name and job properties, and the Child class the hero property. The Child class inherits the name and job properties from the Parent class.

Even in a relatively simple example like this, you can see the OOP approach locks us into a rigid inheritance tree . Every object created with the Child constructor will have a job property now, even though Child objects don’t really need this property.

In contrast, in functional programming we think of our programs more as pipes for data to travel through. We combine multiple simple functions that take in data, conduct some transformation on it, then output the transformed data.

The same example functionally:

In this example, we first define a generic function called giveProp which when given the arguments propName, property, and object, will return a copy of the object with the new property assigned to the property name that we passed in. It is very important for pure functions to only return a copy of the input object and not mutate arguments that were passed in.

This function is intentionally generic because we can reuse it to create more specific functions. We can make the giveProp function more specific by partially applying an argument, or currying. Currying means binding some of the arguments of a function to pre-defined values.

Currying is powerful because we can use it to compose our generic function giveProp into more specific functions that we can use to give a name, job, and hero to our characters.

In this example, I’ve defined a function called curry, which we use to create new giveProp functions with the propName argument already defined. curry takes a function and an argument and returns a function with the first argument already passed in.

For example, I can use curry with the arguments giveProp and a ‘name’ string to create a function called giveName. giveName takes an object and a name as arguments, and will return a copy of the object with the name property assigned to the name value passed in as an argument.

We also use currying to create giveJob and giveHero functions, which like giveName, are more specific versions of giveProp with the propName argument already applied.

Lastly, we can combine our functions to create custom objects. This is called function composition. To create our solo object, we combine the functions giveName and giveJob to create a custom object with a name property and a job property. To create a custom ren object we combine giveName and giveHero to return a custom object with name and hero properties.

If what you read doesn’t make complete sense yet- that’s super ok! The point of this example is to give a high level overview of where we’re headed. The rest of this article will cover the 3 concepts that I introduced: pure functions, currying, and composition. Once you read the rest of this article, please take the time to visit the example above, and you’ll be surprised by how much sense it makes.

Also, another point I wanted to illustrate is that in our functional example, we spent all our time thinking about how to chain functions together to create the output we wanted (ren and vader objects). We spent very little time thinking about the objects themselves. This is the primary difference between FP and OOP thinking. In OOP, we mostly are concerned with inheritance (how objects will receive properties from each other). In FP we are concerned with composition, which is taking generic functions like giveProp, customizing them to specific uses like giveName, and chaining them together to output the data we’re looking for.

Wow. FP is great, where do I start?!

By learning pure functions, currying, and composition. Once you get these 3 concepts down, you’ll not only be prepared to use FP thinking in your everyday programming, but you’ll have the basics to study more complex FP concepts like containers, functors, monads, and applicatives.

So let’s get on with it!

Pure Functions

A pure function is a function that when given a specific input will always return the same output, without causing side effects.

This means that a pure function cannot:

access closure variables (if the closure variable changes, the output of our function will change)

mutate input values (this means if we call the same function again, we may get a different return value, because we changed the input value)

do anything other than return a new value (pure functions can’t do things like make database calls, render HTML, or console.log, because these change the state of our program outside the function. Things that change the state outside the function are called side effects).

I’ve found the easiest way to conceptually think about a pure function is that it is just like a pipe; an input value flows in, something happens to it, and a return value flows out. Input to output, no other side effects happen.

Pure versus impure functions:

Basically, a pure function should not modify its inputs or any variables in its closure scope. Pure functions should only take explicitly declared inputs and return a single output.

Pure functions are the lego blocks that we will build the rest of our functional programs on.

Currying

If you remember our original example, where we created solo and ren objects, we first defined a general function called giveProp. Then we made it more specific by passing in a single argument and returning a new function with the argument already applied. This is how we used giveProps as a building block to create giveName, giveHero, and giveJob without having to rewrite the logic contained within giveProp.

This practice of partially applying a single argument and returning a new function with that argument applied is called currying, named after Haskell Curry, the mathematician who did a lot of the groundwork in the concept. (Sorry, nerdy digression there).

So what problem does currying solve?

If you remember the definition of pure functions, we have to pass in all values used in the function explicitly as arguments. By definition a pure function cannot reference closure variables, because this would make the function output dependent on a value other than its inputs.

But passing in the all inputs as arguments into a function can get rather tiresome. Thankfully by currying functions, we can partially apply one of the arguments and create new, more specific functions.

Enter Ramda. Ramda is a JavaScript library for functional programming with lots of useful utility functions. Think of it as a utility library like underscore or lodash.

With Ramda, we can replace our awkward home-grown curry function with Ramda.curry, which takes a function and returns into the curried version of that function. The curried version of the function can take additional arguments one at a time and return a new function with the argument partially applied. The curried function will not return its value until all arguments have been applied.

First we created a curried function by wrapping our giveProp function with R.curry. By passing in the first argument, propName, into the curried function, we can create new, more specific functions such as giveName, giveJob, and giveHero.

We can continue to curry our functions from there. We can pass in another argument ‘smuggler’ to create a new, more specific function called giveJobSmuggler, which when given an object will return a copy of that object with the a property called job which equals ‘smuggler’.

Finally if we pass in the final argument (the object) into giveJobSmuggler, we’ll finally get the return value out. By currying we can create general building block functions that we can make more specific by passing in additional arguments.

Composition

Now that we have curried functions, we’d like to hook them together, so that we can pipe data through them.

For example, we know to make a ren object, we have to give it a name property, using the giveName function, and we have to give it a hero property using the giveHero function. But how do we chain them together?

We need to chain together two partially applied functions:

giveName(‘Kylo’), which takes an object and returns a copy to that object with the property [‘name’] = ‘Ren’ giveHero(‘Darth Vader’), which takes an object and returns a copy of that object with property [‘hero’] = ‘Darth Vader’

In the above example, we can see two ways to make it happen:

The first way is to create a function in the form f(g(x)). When we pass in a input value x, we first invoke the function g with the value of argument x. We take the return value of g(x) and pass it function f. The return value of the function f, with an argument of g(x) is the final value of the pure function.

In this example we first call giveName on the object passed in as the argument, which will give us a copy of that object with the property [‘name’] = ‘Kylo’. Then we call giveHero on the object returned by giveName, which returns a copy of the object with [‘hero’] = ‘Darth Vader’.

Although this technically works, it’s hard to read these nested functions calls and think about them in a linear way.

Enter compose. Composition means that we attach multiple functions together in a pipe where the return value of the first function becomes the input for the next function.

Note that Ramda’s compose method will apply functions right to left (this is a common pattern in functional programming). So when we call makeRenCompose on an argument object, it first applies giveName, then applies giveHero.

Also note that the makeRenCompose is written in point-free style, which means that the function never explicitly mentions what inputs it operates on. Instead our function is written as a composition of smaller functions, allowing us to read how data will be transformed in a linear way.

Conclusion

Now that we have some understanding of how to use compose, let’s use it to finish our ren and solo objects from the original example, using Ramda.curry Ramda.compose:

Using compose and curry, we can create two functions: makeSolo (which will add name and job properties to any object we pass into it), and makeRen (which will add name and hero properties to any object we pass into it).

I hope this whet your appetite to learn more about functional programming- the benefit is you get to think about your programs as various building block functions composed together, taking data as input, and return the desired values as output.

I’m going to be writing a Part 2 of the Functional JavaScript toolkit, focusing on Containers, Functors, and Monads, but in the meantime, these are excellent resources:

If you’re interested in learning JavaScript web development along with me, follow me on Twitter and Medium!