Functional Programming and Javascript

Gaurav Gera
7 min readNov 9, 2020

Functional programming in the recent years has gained a lot of attention in the Javascript world. Senior Javascript developer interviews require understanding about pure functions, side effects of a function, avoiding shared state and so on. If these topics are alien to you or you might have heard about it from your fellow colleagues but not entirely sure of what does each topic mean. Then this article is for you. I will start this article on Functional programming with WHY, then move on to WHAT and eventually to HOW.

WHY Functional Programming

First, being a Javascript developer you should know multiple ways of achieving a task as Javascript is multi paradigm language, it offers us to write code in object oriented way or functional way and so on. It enhances our capability as a developer. Second, functional programming enhances the predictability of our code making it easier to debug and maintain. Lastly the code is simpler, there is no complex function doing multiple things at one place, instead we have simpler functions doing single task. It embodies the best practices of software development giving us modular and better maintainable code.

Let me give you an example which will explain you why functional programming is awesome.

var obj = {
a: 10
};
func1();
console.log(obj.a); // First
func2();
console.log(obj.a); // Second
func3(obj);
console.log(obj.a); // Third

Now, without knowing the what’s inside func1, func2 and func3 how much confident are you about the value of obj.a at First log, Second log and Third log, not so much? Right!. What if I tell you that this code follows Functional programming approach then you can be 100% sure that value printed on to console will be 10 in all cases. That’s the power of functional programming.

WHAT is Functional Programming

Let’s move on to WHAT. I will not dwell too much into the definition of functional programming as we’ll cover most things in the definition later on in this article. Functional programming is a programming paradigm where we write our application using pure, deterministic functions avoiding side effects and shared state. It is declarative rather than imperative. I know the definition could be a bit harder to grasp, I’ll try to simplify and explain more in detail on this.

Now Let’s get started with the HOW and what are the key concepts of functional programming. How can we write in Functional programming.

Pure Functions

Pure functions are at the heart of Functional programming. Pure functions are functions that depend entirely on the data being passed to it and do not cause any side effects in the application. You give them same input to them n number of times they will give you same output n number times, meaning their function definition does not use any variable outside its own function scope and depends only on the arguments passed to it. Pure functions will not cause any change to a variable outside its scope or the arguments passed to it. Let’s see what we mean by side effects

Possible Side Effects

  1. Changing a global value (variable, property or data structure)
  2. Changing the original value of a function’s argument.
  3. Throwing an exception
  4. Printing to the screen or logging.
  5. Invoking other functions that have side effects.

Now, when you write functions in Functional programming they should Pure. Although writing all functions as Pure functions is almost impossible as we have to write some functions with side effects. In Javascript if we want to write in Functional programming we need to minimise functions with side effects and write as many Pure functions as possible.

Avoid shared state

What is a state? A program is considered stateful if it is designed to remember data from events or user interactions, the remembered information is called state of the program. As Javascript stores data(state) in variables and objects, when a particular object is passed around and modified in different scopes we are sharing state. And this needs to be avoided. A shared scope can include global scope or closure scope.

// Consider below two function foo and bar
// foo is modifying the outer scope variable
const obj1 = {
name: 'Jack'
}
const foo = (newName) => {
obj1.name = newName;
}
const bar = (oldObj, newName) {
return Object.assign({}, oldObj, { name: newName });
}
foo('John'); // This will modify our shared state which obj1bar(obj1, 'Rachel'); // This will not modify our shared state, instead it will
// return a brand new object with updated name for us to start using // this new object. We must write functions following the same idea // of not changing the outer scope objects instead returning new
// object with updated value

Avoid Data Mutation

Functional programming strives toward immutability. If a data object can be changed from multiple places in the code then that object is very difficult to manage and predict its value. With functional programming we want to be completely sure of the value of an object at any particular time to make our life as a developer easier. That’s why immutability is one of the core principles of Functional programming. To create immutable objects Javascript provides various methods like Object.freeze(), Object.defineProperties(). These functions enforces immutability on a object. You can read other blogs to get more detail on how to achieve immutability in Javascript.

First Class Functions

Functions are treated like values, In Javascript functions can be used as value just like a string value or a number value. This means all the below cases of functions are valid.

  1. var func1 = function() {...};
  2. var arr = [28, function() {...}];
  3. var obj = { num: 28, func2: function() {…} }
  4. func3 (10, function() {…})
  5. function func4() { return function() {…} }

Higher Order Functions

Higher order functions are functions that operate on other functions by either taking them as arguments or returning them. The fact that Javascript supports first class functions makes it possible to create Higher order functions. If you see points 4 and 5 in above topic, you will notice that func3 and func4 are Higher order functions.

If you have used map(), filter() or reduce() functions for Arrays you will realise that they are Higher order functions. These functions are heavily used in Functional programming in Javascript. They are declarative as compared to using traditional approach like for loop and generates a new value at each call, meaning it does not mutate the original Array object. I suggest you read about these functions if you haven’t to know more about functional programming in Javascript.

Function Composition

Functions in Functional programming have following attributes
1. Functions have an input.
2. Functions return a value.
3. Functions are simplified to a single task.

Since a function performs a single simpler task, you will need to combine several functions together to achieve a bigger, complex task. This is called Function composition. Function composition is combining multiple functions for the purpose of producing a new function to perform a complex task.
As we move away from a function doing multiple jobs having complex logic to multiple functions doing one job with simple logic we can reuse functions easily, such coding practice increases the reusability of the code.

Now, we can do function composition like below

filerArr(spliVal(capitalize(trunc(str))))

But the above code is difficult to write as well as read.
To solve this Javascript provides a way for us to make the code readable and writable. We can implement our own compose() and pipe() functions for function composition

const compose = function (...fns) {
return function(x) {
return fns.reduceRight(function(v, f) {
return f(v),
}, x)
}
}
// pipe function is similar to compose but it uses reduce function
// You don't have to get into the understanding of compose and //reduce functions right now as they are beyond the scope of this //article
const prepareString = compose(
filterArray,
splitVal,
capitalize,
trunc
);
console.log(prepareString(str))

Here prepareString() is our composed function which we can use wherever we want to call these sequence of functions. Also note we can use individual function like splitVal() as well.

Curry functions

As reduce() and reduceRight() pass only one argument to the function we can use above compose function for only those functions which accept 1 argument. This is a problem. How do we handle functions that accept more than 1 arguments. Here is one use case of curry functions, using curry functions we always apply one argument to a function at a time.

Curry functions transforms a function with arity more than 1 into sequence of functions with argument 1. Let’s look at an example

// This is a function which accepts more than 1 argumentconst add = (a, b) {
return a + b;
}
// now if we want to apply the arguments to the above function one // at a time then we would be need curry functionconst curriedAdd = curry(add);// Now we can pass arguments to curriedAdd() one at time, each time // a function is returned until all the arguments required by add /// have been passed. At the end final value will be returned by //applying all the arguments.curriedAdd(2)(3) // output will be 5// How to use curriedAdd in function compositioncompose(
curriedAdd(2),
getUserInput
)
// Here We have applied 2 as first argument to add and last argument // will be the returned value from getUserInput

Note: This example can be used only when the last argument of the function is expected from the value returned by previous function in function composition.
In case we have to pass the value in any other place then you can use below technique.

compose(
(x) => curriedAdd(x)(2),
getUserInput
)

This is just a brief introduction to functional programming concepts in Javascript. There is a lot more to learn in this. I suggest you to look at the articles published by Eric Elliott on Functional programming to gain more knowledge.

--

--

Gaurav Gera

Senior Frontend developer, Walmart. I am on a path to unravel the brilliancy of Javascript. Ex Adobe