0

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

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

in JavaScript?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Vinay
  • 89
  • 6
  • Well, what have you got so far? – Tyler Aug 22 '14 at 14:54
  • Are we supposed to do it for you or can you share your code and what it isn't doing? – James Black Aug 22 '14 at 14:55
  • 3
    This looks a lot like _currying_, JavaScript can certainly do currying. – Halcyon Aug 22 '14 at 14:55
  • Can you please help me in writing this – Vinay Aug 22 '14 at 14:56
  • you want to be able to call it as `add(3)(5)`? That's not normal syntax for JavaScript (although it would be possible if you abused your add function to return a function... still weird though, and would be very difficult for code writers to understand). Stick to normal syntax and your life will be a lot easier. – Dave Aug 22 '14 at 15:02
  • provide some more information...what you are trying to do?... what is not working... – SK. Aug 22 '14 at 15:03
  • To clarify, you want to be able to call it as `add(3,5)` or as `add(3)(5)` ? A function that can do both? Or just `add(3)(5)`? – xdhmoore Aug 22 '14 at 15:04
  • Woww....Thanks Halcyon for that word "currying". I got it. Can you explain bit about what is currying in javascript? – Vinay Aug 22 '14 at 15:06
  • To answer your question, just write `var add = function () {};` and you're done. So maybe you should put a little more detail into your question, and we can put a little detail more in the answers :) – Hans Roerdinkholder Aug 22 '14 at 15:06
  • 1
    Is that you're asking for? http://jsfiddle.net/vmsy6dvk/ – SiZiOUS Aug 22 '14 at 15:07
  • Yes.. I want to call it as add(3,5) and add(3)(5). Both should work and it should return the sum. – Vinay Aug 22 '14 at 15:08
  • Exactly SiZiOUS. Thank you – Vinay Aug 22 '14 at 15:11

8 Answers8

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.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
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.

xdhmoore
  • 8,935
  • 11
  • 47
  • 90
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));
Vinz243
  • 9,654
  • 10
  • 42
  • 86
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
vis
  • 494
  • 3
  • 9
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;
}
Afsa
  • 2,025
  • 1
  • 16
  • 19
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

SiZiOUS
  • 638
  • 1
  • 8
  • 9
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));
Suchit kumar
  • 11,809
  • 3
  • 22
  • 44
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.

SK.
  • 4,174
  • 4
  • 30
  • 48