What is functional programming?
Functional programming is a programming paradigm where functions are the main building blocks of any program and logics are written inside the functions.
This approach abstracts away the idea of how the action should be performed while emphasizing on what action needs to be performed, thus making the program declarative.
Have a look at the below code snippet.
const sumOfNumbers = (...numbers) => numbers.reduce((total, current) => total + current); sumOfNumbers (1,2,3); sumOfNumbers (2,3,4,5,6);
In the above example we have written a function that calculates the sum of numbers. Ignore the logic of the function for now, if you have to calculate the sum of different numbers; you can just call this function while passing the numbers as arguments to get the result.
In this manner, you can perform the action that needs to be performed without worrying about writing the logic again.
There are many advantages of functional programming,
- Code reusability
- Clean and readable code
- Easy to understand and implement
- Less error prone
- Easy to test
There can be two types of functions:
- Pure functions
- Impure functions
A pure function is a function that takes at least one argument, returns a value or another function and does not change or mutate any of its arguments, whereas a function that violates any of these conditions is called as impure function.
Higher-order function is a function that takes a function as an argument and/or returns a function.
map() is a higher-order function that can be applied to an array in order to transform all the elements of the array. The map() function takes a callback (mapper) function as an argument. It iterates through all the elements of the array one by one and maps them with the callback function and finally returns the new array with the transformed data.
Let's see an example to understand how exactly it works:
const numbers = [2, 4, 6, 8, 10]; const squaredNumbers = numbers.map(num=> num**2); console.log(squaredNumbers); // [4, 16, 36, 64, 100]
filter() is a higher-order function that is used to return a subset of an array based on certain conditions.
As the name suggests, it filters out all the elements fulfilling certain conditions and returns a new array. Syntax wise it is similar to map() as it takes a callback function as an argument that holds the logic of filtering the values and iterating through all the elements to check if the condition is met.
Let's check the example:
const numbers = [1,2,3,4,5,6]; const oddNumbers = numbers.filter(item => item % 2); console.log(oddNumbers) // [1, 3, 5]
reduce() is a higher-order function that is used to return a single item by performing certain action on all the elements of an array.
It can be a bit confusing for the first time, let's directly see the example below:
const numbers = [2,4,6,2,5,7,3]; const total = numbers.reduce((accumulator, current) => accumulator + current, 0); console.log(total); // 29
Well, let's try and understand how exactly reduce works...
reduce(callbackFn, initialValue) takes two arguments; i. a callback function also known as reducer ii. an initial value.
Now the reducer function also takes two arguments: i. accumulator ii. current value
Now if you see in the above example, you'll find:
reducer : (accumulator, current) => accumulator + current;
initial value : 0
accumulator : accumulator
current value : current
The reduce function iterates through each element one by one while performing the action in the callback function and returning the result each time called as accumulator. The result returned by the previous iteration (accumulator) can be used inside the callback function to transform the data based on current element of the array. But what will be the accumulator value in the first iteration? This is where the initial value is used. It's optional to pass the initial value and if not passed, it'll be considered as 0.
Let's try to understand the above example by visualizing it step by step.
Iteration 1 :
accumulator : 0 current value : 2
result returned by the callback function : 0 + 2 = 2
accumulator : 2 current value : 4 result returned by the callback function : 2 + 4 = 6
accumulator : 6 current value : 6 result returned by the callback function : 6 + 6 = 12
accumulator : 12 current value : 2 result returned by the callback function : 12 + 2 = 14
accumulator : 14 current value : 5 result returned by the callback function : 14 + 5 = 19
accumulator : 19 current value : 7 result returned by the callback function : 19 + 7 = 26
accumulator : 26 current value : 3 result returned by the callback function : 26 + 3 = 29
So, it returns the final result as 29 since there is no more iteration left.
Function currying is an important process in functional programming in which a function with multiple arguments can be transformed into a sequence of nested functions with a single argument for each function.
// Normal way const sum = (num1, num2, num3) => num1 + num2 + num3; sum(2, 3, 4); // Function currying const sumCurry = a => b => c => a + b + c; sumCurry (2)(3)(4);
Function composition is combining multiple functions into a single function. If the output of one function needs to be passed into another function as an argument, we can directly call the function inside the outer function rather than storing the result of the first function in a variable and passing it to the other function.
const add = (a, b) => a + b; const square = sum => sum**2; // Normal way const sum = add(2, 3); const squaredValue = square(sum); // Function composition const result = square(add(2,3));
I hope you found it helpful. Feel free to comment your thoughts and add feedback as well.
Have a great day!
Did you find this article valuable?
Support Shahbaz Khan's Blog by becoming a sponsor. Any amount is appreciated!