Composition in JavaScript

In this article, we will explore the concept of composition in JavaScript.

The term "composition" refers to the act of merging two or more elements in order to create a new entity.

Function Composition

  • In JavaScript, there is a technique called the function composition . This technique is utilized to combine two or more functions together and compose a new function.
  • It is a pattern that is utilized to solve the problems. It prevents code redundancy which means there is no need to repeat the code again and again.
  • The purpose of function composition is to take the result of one function and utilize that result as an input for the other function. It is a kind of relationship between functions in which one function consists of another function.
  • The function composition is called higher order functions and compositions because these functions accept other functions as their value.
  • It uses professional composition libraries such as Ramda or Lodash . These libraries make function programming more accessible.
  • Understanding function composition mathematically

When you have two functions, denoted as "a" and "b," the composition of these functions can be expressed as follows:

a(b(x))

The expression a(b(x)) represents the composition of functions, where b(x) is evaluated initially, and the output of function b serves as the input for function a.

Below is a code to compose functions "a" and "b":

Example

const a = x => x + 2;
const b = x => x * 4 ;
const composedFunction = x => a(b(x));
console.log(composedFunction());

To gain a clearer understanding, let's explore a practical example from real life.

We can analyze the concept of function composition through the analogy of assembling a burger, as the majority of us are familiar with the process of creating one.

Consider each step used in making a burger as a function:

  • Burger Bun Slicing Function: A bun is sliced into two parts first.
  • Spreading Function: Spread like butter, hummus, mayonnaise, or any other spread is being put on the bun slice.
  • Filling Function: Filling, such as cucumber, tomato, potato, etc., is added to the bun.

When the functions referenced earlier are merged, a new function is established, known as function composition. This is akin to how the previously created functions come together to form a burger.

Below is a code for creating a burger:

Example

// Burger Bun Slicing Function
const sliceBun = bun => `${bun} is sliced`;

// Spreading Function
const spreadMayonnaise = bun => `Mayonnaise spread on ${bun}`;

// Filling Function
const addFilling = bun => `Filling added to ${bun}`;

// Composition Functions to Make a Burger
const makeBurger = bun => addFilling(spreadMayonnaise(sliceBun(bun)));

console.log(makeBurger("Whole Wheat")); 
// Output: "Filling added to Mayonnaise spread on Whole Wheat is sliced."

Benefits of utilizing a composition function in JavaScript:

-

Reusability and Maintainability:

One of the primary advantages of employing function composition is that each function developed operates independently from the others, allowing for their separate use alongside different functions. This approach facilitates the creation of multiple "composed functions" by reapplying distinct functions.

We have developed a burger by utilizing function composition. By leveraging the same functions, we can also create a bun pudding.

Example

const makeBunPudding = bun => spreadMayonnaise(sliceBun(bun));
console.log(makeBunPudding("Whole Wheat")); 
// Output: "Mayonnaise spread on Whole Wheat is sliced"

In the process of preparing butter bun pudding, we can conveniently utilize the spreadMayonnaise function, which facilitates easy maintenance.

  • Readability:

Dividing a complex task into smaller components makes the code more comprehensible and easier to follow.

  • Immutability:

The composition function is designed to be immutable, meaning that it cannot be altered after its creation. It refrains from altering any existing data; rather, each function produces a fresh value, thereby avoiding unintended side effects.

  • Declarative Programming:

Function composition enhances declarative programming by enabling us to articulate the steps necessary to accomplish our goals, thereby making the code more expressive.

Numerous composition methods exist, including the following:

  • Manual composition:
  • Example
    
    const add = (x) => x + 2;
    const subtract = (x) => x - 1;
    const multiply = (x) => x * 3;
    
    const composedFunction = (x) => multiply(subtract(add(x)));
    
  • Custom Utility Function:
  • Example
    
    const compose = (...funcs) => (x) => funcs.reduceRight((acc, func) => func(acc), x);
    
    const composedFunction = compose(
      multiply,
      subtract,
      add
    );
    
  • Utility Libraries:

Ramda and Lodash are both utility libraries that offer functionalities for composing functions.

Using Ramda:

Example

const { compose } = require('ramda');
const composedFunction = compose(
 multiply,
 subtract,
 add
);

Using Lodash:

Example

const { flow } = require(lodash);
const composedFunction = flow(
 multiply,
 subtract,
 add
);

Conclusion:

In this article, we have explored the concept of composition in JavaScript. Function composition refers to a method employed to merge two or more functions, resulting in the creation of a new function.

Input Required

This code uses input(). Please provide values below: