Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is "Partial Function Application" a misnomer in the context of Javascript?

A friend of mine and I were having a discussion regarding currying and partial function application in Javascript, and we came to very different conclusions as to whether either were achievable. I came up with this implementation of Function.prototype.curry, which was the basis of our discussion:

Function.prototype.curry = function() {
    if (!arguments.length) return this;

    var args = Array.prototype.slice.apply(arguments);
    var mmm_curry = this, args;

    return function() {
        var inner_args = Array.prototype.slice.apply(arguments);
        return mmm_curry.apply(this, args.concat(inner_args));
    }

}

Which is used as follows:

var vindaloo = function(a, b) {
    return (a + b);
}

var karahi = vindaloo.curry(1);
var masala = karahi(2);
var gulai = karahi(3);

print(masala);
print(other);

The output of which is as follows in Spidermonkey:

$ js curry.js
3
4

His opinion was that since the Javascript function primitive does not natively support "partial function application", it's completely wrong to refer to the function bound to the variable karahi as partially applied. His argument was that when the vindaloo function is curried, the function itself is completely applied and a closure is returned, not a "partially applied function".

Now, my opinion is that while Javascript itself does not provide support for partial application in its' function primitives (unlike say, ML or Haskell), that doesn't mean you can't create a higher order function of the language which is capable of encapsulating concept of a partially applied function. Also, despite being "applied", the scope of the function is still bound to the closure returned by it causing it to remain "partially applied".

Which is correct?

like image 643
Nathan de Vries Avatar asked Sep 18 '08 14:09

Nathan de Vries


1 Answers

Technically you're creating a brand new function that calls the original function. So if my understanding of partially applied functions is correct, this is not a partially applied function. A partially applied function would be closer to this (note that this isn't a general solution):

vindaloo.curry = function(a) {
    return function(b) {
        return a + b;
    };
};

IIUC, this still wouldn't be a partially applied function. But it's closer. A true partially applied function would actually look like this if you can examine the code:

function karahi(b) {
    return 1 + b;
};

So, technically, your original method is just returning a function bound within a closure. The only way I can think of to truly partially apply a function in JavaScript would be to parse the function, apply the changes, and then run it through an eval().

However, your solution is a good practical application of the concept to JavaScript, so practically speaking accomplishes the goal, even if it is not technically exact.

like image 174
Michael Johnson Avatar answered Oct 06 '22 03:10

Michael Johnson