0

How to write an add function so that we can call it as

add(3,5);
// and 
add(3)(5); 

in JavaScript?

12
  • Well, what have you got so far? Commented Aug 22, 2014 at 14:54
  • Are we supposed to do it for you or can you share your code and what it isn't doing? Commented Aug 22, 2014 at 14:55
  • 3
    This looks a lot like currying, JavaScript can certainly do currying. Commented Aug 22, 2014 at 14:55
  • Can you please help me in writing this Commented Aug 22, 2014 at 14:56
  • 1
    Is that you're asking for? jsfiddle.net/vmsy6dvk Commented Aug 22, 2014 at 15:07

8 Answers 8

4

Here is a generic way to curry any function as long as it has all its formal parameters defined (i.e. it doesn't work with variadic functions).

function curry(f) {
    return function() {
        if (arguments.length >= f.length) {
            return f.apply(null, arguments);
        }
        var args = Array.prototype.slice.call(arguments, 0);
        return curry(f.bind.apply(f,[null].concat(args)));
    }
}

It works by comparing the number of parameters the function accepts (exposed via the .length property) to the number of arguments passed to the function. If less arguments are passed to the function than it accepts, it returns a new function with bound parameters.

Usage:

function add(a, b, c) {
    return a + b + c;
}

add = curry(add);

console.log(add(1,1,1));   // 3
console.log(add(1,1));     // function
console.log(add(1,1)(2));  // 4
console.log(add(1)(2,2));  // 5
console.log(add(1)(2)(3)); // 6

Demo: http://jsfiddle.net/90zs4n92/


An alternative implementation which avoids binding arguments can be found here.

Sign up to request clarification or add additional context in comments.

1 Comment

Really brilliant! This approach is really smooth.
0

This is the solution based on my original comment. By the way I see that everyone there had the same idea (returning a function object.).

var add = (function(x, z) {
    return (typeof(z) !== "undefined") ? x + z : function(y) { return x + y; }
});

var value = add(3)(5);
alert(value); // 8

value = add(3, 5);
alert(value); // 8

If the original goal of your question was about currying, I found a document interesting about that, using JavaScript : https://medium.com/@kbrainwave/currying-in-javascript-ce6da2d324fe

Comments

0

Perhaps this is what you want?

function addFactory(a) {
  return function(b) {
    return a + b;
  };
}

//Make an addingFunction
var addThree = addFactory(3);

addThree(5);  // returns 8

//Or, in short
addFactory(3)(5);  // returns 8

You could probably make the function handle both the add(3,5) case and the add(3)(5) case by checking arguments.length and the type of the arguments. However, I would imagine it would be easier and more readable just to have 2 functions with an if statement. Not sure what you're using it for.

Comments

0

This will work with either way:

add = function(a, b) {
    if(b === undefined) {
        return function(b) {
            return add(a, b);
        }
    }
    return a + b;
}
alert(add(3)(5));
alert(add(3, 5));

Comments

0

You want to write a curryable function - a function that takes n amount of arguments, but if you call it without all the arguments, it returns a partially applied function.

var add = function(a, b) {
    if(arguments.length === 2) {
        return a + b;
    }
    else {
        return function(x) { return x + a }
    }
}

var addFour = add(4); 

add(4, 3); // => 7
add(4)(3); // => 7
addFour(3); // => 7

Comments

0

Try this

function add() {
   //Check the number of arguments
   var argLength = arguments.length;

   //No arguments
   if(argLength == 0) {
      return null;
   }

   //Only one argument, then return another function. 
   if(argLength == 1) {
      var first = arguments[0];
      return function(second) {
         return first + second;
      }
   }

   //More than one argument, then add them all.
   var output = 0;
   for(var i = 0; i < argLength; i++) {
      output += arguments[i];
   }
   return output;
}

Comments

0

you can do this:

   function add(a, b) {
    if(b === undefined || arguments.length !== 2) {
        return function(b) {
            return add(a, b);
        }
    }
    return a + b;
}
alert(add(3)(5));
alert(add(3, 5));

Comments

0

Currying is when you break down a function that takes multiple arguments into a series of functions that take part of the arguments. Here's an example in Scheme

(define (add a b)
(+ a b))

(add 3 4) returns 7

This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:

(define (add a)
    (lambda (b)
        (+ a b)))`

This is a function that takes one argument, a, and returns a function that takes another argument, b, and that function returns their sum.

((add 3) 4)

(define add3 (add 3))

(add3 4)

The first statement returns 7, like the (add 3 4) statement. The second statement defines a new function called add3 that will add 3 to its argument. This is what some people may call a closure. The third statement uses the add3 operation to add 3 to 4, again producing 7 as a result.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.