Note: This is part of the “Javascript and Functional Programming” series on learning functional programming techniques in JavaScript ES6+. To start from the ground up check out

Welcome to the Upside Down

Before we get started, there’s something you need to know … If you’ve ever programmed in JS you’ve probably used FP patterns before! These patterns and paradigms have been there all along, we just haven’t been able to see them properly. We are going to start from the familiar and explore new territory. Things may get a bit … well … strange. But fear not! Together we will survive!

Welcome to the Upside Down

Before we get started, there’s something you need to know … If you’ve ever programmed in JS you’ve probably used FP patterns before! These patterns and paradigms have been there all along, we just haven’t been able to see them properly. We are going to start from the familiar and explore new territory. Things may get a bit … well … strange. But fear not! Together we will survive!

A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.

Functions as constants

In the following example we will declare a const and assign it an anonymous arrow functions.

After the initial assignment constFunction is a constant with a value of a function. We verify that by logging the constFunction variable in the Chrome inspector. Because constFunction is a function we can also invoke it.

Functions as values of keys of an object

const functionAsObjectProperty = { print: (value) => console.log(value) }; functionAsObjectProperty.print("mic check"); // "mic check"

Functions as array items

Now that we understand that variables can hold functions, let’s demonstrate a function as a value of a key in an object. This should be familiar for anyone who has done any object oriented programming before.When functions are first class objects we can pass them as data to an array, just like any other data type. Let’s use the Chrome console and check this out.

Higher order functions

Now that we’ve warmed up, let’s get to the interesting stuff :) JS developers see functions that accept other functions as arguments on a daily basis. If you’re coming from a language that doesn’t support FP this should seem a bit weird 😳😳😳😳😳😳😳 Let’s acquaint ourselves with this concept by looking at some examples.

An asynchronous function that accepts a callback function.

const jsonfile = require('jsonfile') const file = '/tmp/data.json' const obj = {name: 'JP'} const errorLoggerFunction = (err) => console.error(err); jsonfile.writeFile(file, obj, errorLoggerFunction)

errorLoggerFunction is defined as a function with the ES6 arrow syntax

We’re using the jsonfile npm module in this example for the writeFile method. The third parameter that writeFile is expecting is a function. When the jsonfile.writeFile method executes it will either succeed or fail. If it fails it will execute the errorLoggerFunction. Alternatively, we could have gone for a more terse syntax, and dropped the named function:

const jsonfile = require('jsonfile') const file = '/tmp/data.json' const obj = {name: 'JP'} jsonfile.writeFile(file, obj, (err) => console.error(err))

It’s an anonymous function because we didn’t name it

setTimeout

const timeout = () => { setTimeout(() => alert("WoW"), 1000); }

Classic callback example

This example shows the built in asynchronous setTimeout method which accepts 2 arguments. Let’s formalize this a little bit and explain the setTimeout function in functional programming terms.

Let’s start by reading the signature of the function. We can observe that the number of arguments that setTimeout takes is two. In functional programming the number of arguments a function takes is called its Arity, from words like unary, binary, ternary etc. So we can say that setTimeout is of arity 2, or equivalently say that is a binary function.

The arguments that setTimeout expects is a function and a time interval to wait before executing the given function. Hmmm … another function that accepts a function as input?

In functional programming this is so common that these types of functions even have a name! They are called higher order functions.

A higher order function is a function that takes a function as an argument, or returns a function.

There you go. Now you can drop this term low key in any random conversation at work / with friends and sound like a boss! 😂😂😂

You can’t be wrong if no one understands what you’re saying

Let’s get a little funkier and create an array (list) of functions in the next example.

const add = (x,y) => x + y; const subtract = (x,y) => x - y; const multiply = (x,y) => x * y; const arrayOfFunctions = [add, subtract, multiply]; arrayOfFunctions.forEach(calculationFunction => console.log(calculationFunction(1,1))); // 2 0 1

On line 5 we are declaring an array of functions. We are then using the forEach method to iterate over the array. forEach is a natively supported ES6+ function, that accepts a function to execute on every item in the array. Therefore, forEach is also a higher order function!

Our forEach accepts an anonymous function as input. forEach will iterate over the array and implicitly access the current item in the array and call it getCalculation. It is worth noting that forEach implicitly accesses array elements, in comparison to how we would have accessed the current element if we had used a regular for loop — ie. arrayOfFunctions[i]. Every item in our array is a function, therefore we invoke getCalculation with the arguments that it is expecting.

Fantastic. This example illustrates that functions in functional programming can be passed into arrays (lists) just like any other data type. Functions can go anywhere!

Now let’s build our own higher order function!

const addWrapper = () => (x,y) => x + y; const add = addWrapper(); const sum1 = add (1,2); // 3 // Or we could do it like this const sum2 = addWrapper()(4,4); // 8

addWrapper is a function that accepts a function as an argument

The addWrapper function returns a simple addition function when called. By invoking the result of the addWrapper function and supplying it two arguments, we have access to the anonymous addition function.

We could get even crazier with our level of indirection and write a function that returns a function, that in turn returns its own function!

const bankStatement = name => location => balance => `Hello ${name}! Welcome to the bank of ${location}. Your current balance is ${balance}`; const statementExpectingLocation = bankStatement("Omer"); const statementExpectingBalance = statementExpectingLocation("NYC"); const bankStatementMsg = statementExpectingBalance("100 million"); // wishful thinking? console.log(bankStatementMsg); // Hello Omer! Welcome to the bank of NYC. Your current balance is 100 million // We could also call the function with all the arguments up front const msg = bankStatement("Jeff Bezos")("Silicon Valley")("97.7 billion"); console.log(msg); // Hello Jeff Bezos! Welcome to the bank of Silicon Valley. Your current balance is 97.7 billion

I hope you like curry!

This is a very powerful pattern in functional programming. We will explore it in depth in the coming posts when we talk about currying and partial applications.

First class functions are the cornerstones of any functional programming language. The main point that you should take away from our discussion about first class functions is that functions can be assigned as constants, variables, placed as array elements and even set as values of keys on an object. Additionally, (and most importantly ?!) functions can be returned to and from functions — just like any other data type!

If you’re passionate about Front End development, check out the JavaScript Works job-board here!