Wayne Ho
Wayne Ho

Reputation: 45

How to implement currying in javascript?

Question as below:

create a sum function, and the requirement:

sum(1,2).result === 3
sum(1,2)(3).result == 6
sum(1,2)(3,4).result == 10
sum(1,2)(3,4)(5).result == 15

This is a question about currying in JS. I have implemented the most functions of the question. The tricky point is .result for me.

What does .result means after sum(1,2)? Is it an attribute?

How to add the .result to my code?

function sum(){
    var count = 0;
    for(let i=0; i<arguments.length; i++){
        count += arguments[i];
    }
    var tmp = function(){
        for(let i=0; i<arguments.length; i++){
            count += arguments[i];
        }
        return tmp;
    }
    tmp.toString = function(){
        return count;
    }
    return tmp;
}

console.log(sum(1,2))
console.log(sum(1,2)(3))

Upvotes: 0

Views: 1093

Answers (4)

Ilijanovic
Ilijanovic

Reputation: 14904

Here a solution. It always better to use spread operator on the arguments instead of using arguments keyword. Witch should be avoided

function sum(...args){
    let count = 0;
    count += args.reduce((a,v) => a + v);
    let res = sum.bind(this,count);
    res.result = count;
    return res;
}

console.log(sum(1,5)(4)(5).result)

Upvotes: 0

Tejas Savaliya
Tejas Savaliya

Reputation: 638

Currying is an advanced technique of working with functions. It’s used not only in JavaScript, but in other languages as well.

Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c).

Currying doesn’t call a function. It just transforms it.

Let’s see an example first, to better understand what we’re talking about, and then practical applications.

We’ll create a helper function curry(f) that performs currying for a two-argument f. In other words, curry(f) for two-argument f(a, b) translates it into a function that runs as f(a)(b):

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// usage
function sum(a, b) {
  return a + b;
}

let curriedSum = curry(sum);

alert( curriedSum(1)(2) ); // 3

Also Refer this link for more details

Upvotes: 0

priyadarshi kumar
priyadarshi kumar

Reputation: 192

Shrey answer is Perfect but we can make it more sorter and clear.

function sum() {
    let result = [...arguments].reduce((acc, num) => acc + num, 0);
    let newSum = sum.bind(this, result);
    newSum.result = result;
    return newSum;
}

console.log(sum(3,4)(5)(9).result);
console.log(sum(3,4)(5,6)(9).result);

Upvotes: 0

Shrey Gupta
Shrey Gupta

Reputation: 392

You can add .result to your code by storing result as a property in function.

You can also remove the redundant tmp function code . Here is how it looks:

function sum(){
    var count = 0;    // use previous result
    for(let i=0; i<arguments.length; i++){
        count += arguments[i];
    }
    const newSum = sum.bind(this,count);
    newSum.result = count;
    return newSum;
}

console.log(sum(1,2).result)
console.log(sum(1,2)(3).result)

.bind() here binds the first argument of cloned function (newSum) as count , which will be used on all subsequent calls

Upvotes: 3

Related Questions