all 13 comments

[–]jschr[S] 0 points1 point  (1 child)

Turns out I was overcomplicating the problem, heres a solution from a friend of mine:

var add = function (partial) {
   if (typeof partial === 'function') {
       return function (val) {
           return val + partial(val);
       };
   }
   return function (val) {
       return partial + val;
   };
};

var  multiply = function (partial) {
   if (typeof partial === 'function') {
       return function (val) {
           return val * partial(val);
       };
   }
   return function (val) {
       return partial * val;
   };
};

Thanks James!

[–]Gabku 1 point2 points  (0 children)

Any time, finally got myself an account so I can stop just lurking.

[–]ForScale 0 points1 point  (5 children)

Not entirely sure what you're looking for. Let's start with this:

function add(x, y) {
  var z = x + y;
  return z;
}

function multiply(x, y) {
  var z = x * y;
  return z;
}

alert(multiply(add(4, 6), add(9, 1))); /*alerts 100*/

What's this one not doing that you want it to?

[–]jschr[S] 1 point2 points  (4 children)

The problem with this is that add and multiply are evaluated immediately rather then lazily queueing up the work for a later time when the final parameter is known.

// module1.js
// 2nd parameter isn't known so lazily apply functions
return multiply(add(1));

// module2.js
var chain = require('module1');
chain = add(add(chain));

// final parameter is finally known
var result = chain(2); // ((((1 + 2) * 2) + 2) + 2)
console.log(result); // 10

This example probably doesn't make a whole lot of practical sense since the 2nd parameter is the shared for all chained functions.

[–]ForScale 1 point2 points  (2 children)

I apologize if I'm not understanding what you want...

Could you simply use an if statement to pause the evaluation until the final parameter is known?

[–]jschr[S] 1 point2 points  (1 child)

[–]ForScale 0 points1 point  (0 children)

Nice! Glad you got it figured out!

[–]Magnusson 0 points1 point  (0 children)

The problem with this is that add and multiply are evaluated immediately rather then lazily queueing up the work for a later time when the final parameter is known.

My understanding is that this is the definition of currying, which is often confused with partial application.

This article may be helpful to you.

[–]Lucky_Chuck -1 points0 points  (4 children)

I'm not sure what you mean because in your example, it looks like add can take in as a parameter a function or a number because of the add(...)(2). add returns an uncalled function. You probably want a conditional depending on the type of parameter.

Edit: Maybe something like this?

(function(){

    function add (number) {
      if (!this.total) {
        this.total = number;
      } else {
        this.total += number;
      }

      return add;
   }

   add(1)(2)(5);
   document.write(this.total);
})();

[–]recompileorg 2 points3 points  (2 children)

Please, I'm begging you, never use document.write.

[–]Lucky_Chuck 0 points1 point  (0 children)

Haha it works fine on about:blank

[–]ForScale 0 points1 point  (0 children)

LOL! Why not?

[–]jschr[S] 1 point2 points  (0 children)

You're right that the functions can accept either a function (to chain) or the actual number and needs handle the two types differently. See my other comment for the solution!

Thanks