Implementing a Curried Sum Function
Question Link: https://bigfrontend.dev/problem/create-a-sum
Our goal is to achieve the following functionality:
const sum1 = sum(1)
sum1(2) == 3 // true
sum1(3) == 4 // true
sum(1)(2)(3) == 6 // true
sum(5)(-1)(2) == 6 // true
As we see, we need to have some sort of method/functional chaining, to do this we can be sure that the sum
function should return a function which in turn can be called over and over again thereby forming a chain.
And the way we will achieve this is by utilizing the concept of Currying
What is Currying?
Currying in JavaScript is a technique wherein a function that can take multiple arguments is transformed to a function that takes a single argument and returns a function that in turn takes the further arguments, and so on until all the arguments are received.
Approach
Return an inner function from the
sum
function. This inner function takes the next argument of the chain and adds it to the current sum argument.This happens because the inner function forms a closure with the sum function and remembers the lexical environment (which includes the arguments) even when it's called individually
- Then the recursive call happens with the updated argument passed to sum and inner function again having access to this updated argument. (This will be clear with the breakdown below)
In the end since we are returning the inner function itself but we need to compare the final sum with the given value
To achieve this we alter the .valueOf property through which we’ll return the num argument which will help us compare. The reason for this is when a function is compared to a primitive value , the valueOf property is called and the assigned function is executed.
Let’s understand it with an example
function returnTwo(){
console.log("Does Nothing")
}
returnTwo.valueOf = () => 2
returnTwo == 2 // returns true
// Because when returnTwo == 2 is executed,
// the .valueOf function of the returnTwo object is called
// and it returns 2 due to type coersion in case of "=="
// and it'll fail in case of "===" because of no type coersion (it strictly checks a functional object to a primitive number)
Code
function sum(num) {
const innerFunction = (nextVal) => sum(num+nextVal)
innerFunction.valueOf = () => num
return innerFunction;
}
Visual Walkthrough
Consider the example sum(5)(-1)(2)
, below is the visual flow of how the code will execute which helps better grasp and understand the flow
With that we’re able to solve this problem of creating a curried sum.
Ending this blog with a positive note to help fuel your day towards your endeavors: