Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to partially apply member functions in JavaScript?

I currently have a partial-application function which looks like this:

Function.prototype.curry = function()
{
    var args = [];
    for(var i = 0; i < arguments.length; ++i)
        args.push(arguments[i]);

    return function()
    {
        for(var i = 0; i < arguments.length; ++i)
            args.push(arguments[i]);

        this.apply(window, args);
    }.bind(this);
}

The problem is that it only works for non-member functions, for instance:


function foo(x, y)
{
    alert(x + y);
}

var bar = foo.curry(1);
bar(2); // alerts "3"

How can I rephrase the curry function to be applied to member functions, as in:

function Foo()
{
    this.z = 0;

    this.out = function(x, y)
    {
        alert(x + y + this.z);
    }
}

var bar = new Foo;
bar.z = 3;
var foobar = bar.out.curry(1);
foobar(2); // should alert 6;
like image 447
bfops Avatar asked Jul 07 '11 17:07

bfops


People also ask

How do you use partials in JavaScript?

Partials are basically functions that return functions with some already predefined arguments and need some arguments to be completed. Let's say you have a function with several arguments to be set, but you don't want to set the majority of arguments over and over again because you need it more than once.

How does partial application function work?

Partial Application: The process of applying a function to some of its arguments. The partially applied function gets returned for later use. In other words, a function that takes a function with multiple parameters and returns a function with fewer parameters.

What is the difference between currying and partial application?

Simple answer. Currying: Lets you call a function, splitting it in multiple calls, providing one argument per-call. Partial Application: Lets you call a function, splitting it in multiple calls, providing multiple arguments per-call.

Does Java support partial function applications?

Java still has a long way to go, but they made functional programming in Java easier. For example, we can now do simple partial application. This Java version is more limited than the Clojure one. It can only take a two argument function, whereas Clojure's supports arbitrarily many arguments.


2 Answers

Instead of your curry function just use the bind like:

function Foo()
{
    this.z = 0;

    this.out = function(x, y)
    {
        alert(x + y + this.z);
    }
}

var bar = new Foo;
bar.z = 3;
//var foobar = bar.out.curry(1);
var foobar = bar.out.bind(bar, 1);
foobar(2); // should alert 6;
like image 125
Prusse Avatar answered Oct 17 '22 17:10

Prusse


You're close. this.z inside of this.out references the this scoped to the function itself, not the Foo() function. If you want it to reference that, you need to store a variable to capture it.

var Foo = function() {
    this.z = 0;
    var self = this;

    this.out = function(x, y) { 
        alert(x + y + self.z);
    };
};

http://jsfiddle.net/hB8AK/

like image 34
Robert Avatar answered Oct 17 '22 16:10

Robert