Javascript usages of bind vs curry?

Royi Namir picture Royi Namir · Mar 2, 2014 · Viewed 6.9k times · Source

I'm trying to understand the difference between curry vs bind.

The implementation of bind is :

/*1*/   Function.prototype.bind = function ()
/*2*/   {
/*3*/        var fn = this,
/*4*/           args = Array.prototype.slice.call(arguments);
/*5*/       var object = args.shift();
/*6*/       return function ()
/*7*/       {
/*8*/           return fn.apply(object, 
/*9*/                           args.concat(Array.prototype.slice.call(arguments)))
/*10*/       };
/*11*/   }

The implementation of curry is :

/*1*/   Function.prototype.curry = function ()
/*2*/   {
/*3*/       var fn = this,
/*4*/           args = Array.prototype.slice.call(arguments);
/*5*/       return function ()
/*6*/       {
/*7*/           return fn.apply(this, 
/*8*/                           args.concat(Array.prototype.slice.call(arguments)));
/*9*/       };
/*10*/   };

I already know that curry is not an internal function (unlike bind which is in IE9+). But still:

Why do I hear people keep talking about curry , While they can simply use bind operation ?

The only difference is the context which is actually found only at the bind function.

differences

enter image description here

Example :

Let's say I have this function :

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

I could do it with curry :

alert(add.curry(2).curry(1)(4)) //7

But I could also do it with :

alert(add.bind(undefined,2).bind(undefined,1)(4)) //7

I don't understand why this curry term function exists while it is possible to add a dummy context to the bind function.

What am I missing ?

Answer

James picture James · Mar 2, 2014

There is a difference in intention.

Currying is to reduce the number of arguments, usually to avoid calling a function a lot with the same initial arguments. For example:

var celsiusToKelvin = add.curry(273.15);

bind() is to make sure that a function is attached to an object. It also happens to offer a currying facility, so yes you can use bind() to curry(), but if you want to curry, curry() has fewer arguments and shows your intention.