A practical introduction into functional programming with JavaScript.

Many articles talk about advanced functional programming topics, but I want to show you simple and useful code that you can use in the day to day developer life. I’ve chosen JavaScript because you can run it almost everywhere and it’s well suited for functional programming. Two of the reasons why it’s so great are that functions are first class citizens and you can create higher-order functions with it.

Update: You can also read this post on DZone.

Higher order functions are functions that can take a function as an argument or return a function as a result. Such as createAdd below:

function createAdd(a){
    return function(x){
        return a + x;
    }
}

add3 = createAdd(3);

console.log( add3(5) );
//output is 8

Note how you can store a function in a variable and call it later. Functions in variables are treated as just any other variable.

typeof add3
"function"

But why is it great that you can return a function as a result? Because you are able to return behaviour not just values and because of this the abstraction will be higher and the code will be more readable and elegant.

Let’s take an example, you want to print the double of every number in an array something that every one of us does once in a while, you would probably do something similar:

nums = [1, 2, 3, 4, 5];

for (x = 0; x < nums.length; x++) {
    console.log(nums[x] * 2);
}

You can see a common pattern here, the looping through an array is a behaviour that you can extract into a function so you don’t have to write it again.

How to do it?

nums = [1, 2, 3, 4, 5];

printDouble = function (k) {
    console.log(k * 2);
}

function forEach(array, functionToRunOnEveryElement) {
    for (x = 0; x < array.length; x++) {
        functionToRunOnEveryElement(array[x]);
    }
}

forEach(nums, printDouble);

// output: 
// 2 
// 4 
// 6 
// 8 
// 10

The forEach function gets an array of numbers and a function printDouble and calls printDouble on every element of the array. Actually, this is a very useful function and its implemented in the prototype of array. So you don’t have to write the previous code in every codebase that you work on.

(forEach is a higher-order function too because it takes a function as a parameter.)

nums = [1, 2, 3, 4, 5];

printDouble = function(k){
    console.log(k * 2);
};

nums.forEach(printDouble);

// output:
// 2
// 4
// 6
// 8
// 10

Welcome to a life without having to write loops again to do something with an array.

You can also write the previous code this way:

[1, 2, 3, 4, 5].forEach((x) = > console.log(x * 2))

Javascript has abstractions for similar common patterns such as:

  • Reduce can be used to have a single output from an array.
nums = [1, 2, 3, 4, 5];

add = function (a, b) {
    return a + b;
}

nums.reduce(add, 0);

//returns 15

What it does is:

0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
  • Map is similar to forEach but the function you give in modifies the value of the current element:
nums = [1, 2, 3, 4, 5];

function isEven(x) {
    if (x % 2 == 0) {
        return x + " is an even number";
    } else {
        return x + " is an odd number";
    }
}

nums.map(isEven)

// returns an array:
// [ '1 is an odd number',
// '2 is an even number',
// '3 is an odd number',
// '4 is an even number',
// '5 is an odd number' ]
  • filter is used for removing the element that do not match a criteria:
nums = [1, 2, 3, 4, 5];

isEven = function(x){
    return x % 2==0;
};

nums.filter(isEven);

//returns an array with even numbers [ 2, 4 ]

or with using the fat arrow operator:

[1,2,3,4,5].filter((x) => {return x%2==0});

A similarly common example for a web application:

function addAMonthOfSubscriptionToUser(username) {
    user = db.getUserByUsername(username);
    user = addAMonthOfSubscription(user);
    db.saveUser(user);
}

function addAYearOfSubscriptionToUser(username) {
    user = db.getUserByUsername(username);
    user = addAYearOfSubscription(user);
    db.saveUser(user);
}

function cancelSubscriptionForUser(username) {
    user = db.getUserByUsername(username);
    user = cancelSubscription(user);
    db.saveUser(user);
}

addAMonthOfSubscriptionToUser("Jay");

Don’t repeat yourself – as every good programmes knows

In this scenario, we can see a pattern, but it cannot be abstracted with OOP structures so let’s do our functional magic.

modifyUser = function(modification){
   return function(username) {
       user = db.getUserByUsername(username);
       user = modification(user);
       db.saveUser(user)
   }
}

addAMonthOfSubscriptionToUser = modifyUser(addAMonthOfSubscription);
addAYearOfSubscriptionToUser = modifyUser(addAYearOfSubscription);
cancelSubscriptionForUser = modifyUser(cancelSubscription);

addAYearOfSubscriptionToUser("Bob");

In the end, we have the same functions in a more elegant way.

I think in the future functional programming will creep into our everyday life and will be used beside with OOP so we can have a more abstract and readable codebase.

The cost of all this nice and abstract code is efficiency and more expensive developers.

Leave a Reply

Your email address will not be published. Required fields are marked *