Function Composition In JavaScript with multiple parameters
Tags: javascript, es6, functional
Published: 2022-05-07 15:08:39

Function composition in JavaScript is process of combining several function calls into one function.

Ways in which function composition can be done

1. Creating a high-order function and pass the necessary functions as parameters in this method.
2. Using `reduce()` or `reduceright()` function and pass all the independent functions that needs to be combined.

Let's see how can this be done

### Approach 1 : Using higher order functions


**UseCase:** If we have a scenario where we need to print details of employee on some kind of employee card for each employee and we have three independent functions.
Code for the example is written below

```javascript
	
	// function1 to print employee id
	const printId = (employeeId) =>{
	  console.log("Printing| EmployeeId:", employeeId);
	}
	
	//function2 to print employee name
	function printname(name) {
	  console.log("Printing| Name:", name);
	}
	
	//function3 to print email and designation among other info.
	const printOther = (email, designation) =>{
	  console.log(`Printing| Email: ${email} ,Designation: ${designation}`);  
	}
	
	//function 4 is an higher order function that runs the functions being passed into it
	const print = (funcA, funcB) => (param_ToFunctionB) =>
	  funcA(funcB(param_ToFunctionB));
	
	
	//printing the combination of above js functions
	print(
	  printId(1234),
	  print(
	    printname("Rahul"),
	    printOther("rahul@web.com", "software engineer")
	  )
	);
	
	//output
	Printing| EmployeeId: 1234
	Printing| Name: Rahul
	Printing| Email: rahul@web.com ,Designation: software engineer
	

```
the `print(funcA, funcB)` function takes a bigger form .i.e. more lines of code when we need to add more functions to the composition.

### Approach 2: Using reduce() or reduceRight() functions for function composition

For same use case as above , second way of doing function composition in JavaScript is by using `reduce()` or `reduceRight()` functions.
	
JavaScript `reduceRight()` function runs a function on each element of the array to reduce it into a single value. Also , `reduceRight()` function executes elements from the right, whereas reduce() method executes elements from left.
	
> It is noteworthy that functions objects being passed to the `reduce()` or `reduceRight()` function should have same number of arguments in each of them, and it should also return one value 
So, any function can be made composable by converting that function into a curry function
	
_Currying_ is the technique in functional way of programming of transforming a function taking multiple input arguments (two, three or more- polyadic) into set of internally related functions by using closures, where each function is single input, single output function, and final output returned from the outermost function.
	
> Simply written, _currying_ is the way of reshaping the function type `f(a, b, c)` to `f(a)(b)(c)` .
	e.g.
```javascript
	//normal function call
	const departmentEmployees=(departmentName,empId,empName)=>{
	    console.log(`${departmentName} Info| ${empId} :: ${empName}`);
	    return true;
	}
	//transformed carried function
	const departmentCarryTransformed = (departmentName)=>(empId)=>(empName)=>{
	    console.log(`${departmentName} Info | ${empId} :: ${empName}`);
	        return true;
	}
	//carry function benefit
	//we can create single global variable for a department and use it elsewhere across the file or the page
	let accountsDepartment= departmentCarryTransformed("Accounts");
	accountsDepartment(123)('bob');
	accountsDepartment(2)('tom');


```	
So, functions in this case

```javascript
	// function1 to print employee id
	const printId = (attributes) => {
	  console.log("Printing| EmployeeId:", attributes.employeeId);
	  return attributes;
	};
	
	//function2 to print employee name
	function printname(obj) {
	  console.log("Printing| Name:", obj?.name);
	  return obj;
	}
	
	
	//function3 to print email and designation among other info.
	const printOther = (attributes) => {
	  console.log(
	    `Printing| Email: ${attributes?.email} ,Designation: ${attributes?.designation}`
	  );
	};
	
	
	// TO make the function composition easier, we can use rest parameters to pass indefinite number of arguments to the function
	const smarterPrint =
	  (...functions) =>
	  (params) =>    functions.reduceRight((p, fn) => fn(p),params);
	
	
	// parameters that we need to pass to different functions to print specific info
	const fn_params = {
	  employeeId: 1234,
	  name: "rahul ranjan",
	  email: "rahul@web.com",
	  designation: "software engineer",
	};
	
	// this function composition way takes lesser code of lines.
	smarterPrint(printOther, printname, printId)(fn_params);
	
	// second way
	const smarterPrintOtherWay = (paramsObj) => printOther(printname(printId(paramsObj)));
	
	smarterPrintOtherWay(fn_params);
	
	//output is same 
	Printing| EmployeeId: 1234
	Printing| Name: Rahul
	Printing| Email: rahul@web.com ,Designation: software engineer


```

The benefit of this approach for function composition is visually seen as our code base increases.

References

- https://javascript.info/currying-partials
- https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/
- https://medium.com/hackernoon/javascript-functional-composition-for-every-day-use-22421ef65a10