A. Sharif

Partial Application And Currying In Javascript

03 May 2014

Introduction

The following article should highlight the difference between partial application and currying.

Partial Application

In short a partial function application expects a function and returns the same function with fewer arguments by binding pre defined arguments to the function. Take a look at the following example:

function sumUpTheThree(a, b, c) {
    return a + b + c;
}

What if we only had variable a defined and wanted to bind the value to the function? This is how the most basic solution would look like (f.e. we know that a = 1):

function sumUpTheThreeMinusA(b, c) {
    return sumUpTheThree(1, b, c);
}

sumUpTheThreeMinusA(2, 3);

We could even simply use Function.prototype.bind() method and would have the same result:

var sumUpTheThreeMinusA = sumUpTheThree.bind(null, 1);
sumUpTheThreeMinusA(2, 3);

The second approach is of course more effective than the first, bind() returns a new function with the provided arguments being set when calling the function. This would also work:

var sumUpTheThreeMinusA = sumUpTheThree.bind(null, 1, 2);
sumUpTheThreeMinusA(3);

Passing more arguments will have no effect on the result:

var sumUpTheThreeMinusA = sumUpTheThree.bind(null, 1, 2);
sumUpTheThreeMinusA(3, 4, 5, 6);

Custom Function

We should have a basic idea of partial application now. But we can take it a step further and write our own simple function that will take care of returning a function with predefined values:

function partialApplication(fn) {
    var args = Array.prototype.slice.call(arguments, 1);

    return function() {
      return fn.apply(this, args.concat(Array.prototype.slice.call(arguments, 0)))
    };
}

We will use the previous example for verifying that this custom function will do what it should:

var sumUpTheThreeMinusA = partialApplication(sumUpTheThree, 1);
sumUpTheThreeMinusA(2, 3);

var sumUpTheThreeMinusA = partialApplication(sumUpTheThree, 1, 2);
sumUpTheThreeMinusA(3);

Partial Application With Wu.js

Of course we do not need to write our own partial application function as a couple of libraries already offer abstractions including wu.js and lodash. To round up the partial application part we will have a look at how simple it is to use wu.js to create a partial application.

var sumUpTheThreeMinusA = wu.partial(sumUpTheThree, 1);
sumUpTheThreeMinusA(2, 3);

var sumUpTheThreeMinusA = wu.partial(sumUpTheThree, 1, 2);
sumUpTheThreeMinusA(3);

We can even do this (we know a and c but we do not have b):

var sumUpTheThreeMinusA = wu.partial(sumUpTheThree, 1, wu.___, 3);
sumUpTheThreeMinusA(2);

Currying

Currying creates multi parameter functions by composing single parameter functions.

Take a look at the following:

function sumUpTheThree(a) {
    return function(b) {
        return function(c) {
            return a + b + c;
        }
    }
}

and then:

sumUpTheThree(1)(2)(3);

In javascript we simply wrote this:

function sumUpTheThree(a, b, c) {
    return a + b + c;
}

Custom Function

We will write a custom function that will return a function until all parameters have been defined.

function currying(fn) {
    len = fn.length;

    function curryFn(prev) {
      return function(args) {
        args = prev.concat(args);
        return (args.length < len)? curryFn(args) : fn.apply(this, args);
      };
    }

    return curryFn([]);
}

Let's test the custom method:

var curryTest = currying(sumUpTheThree);
curryTest(1)(2)(3);

Which could also be written like this:

var curryTest = currying(sumUpTheThree);
var curryTestB = curryTest(1);
var curryTestC = curryTestB(2);
curryTestC(3);

Currying With Wu.js

Finally we will have a look at how to achieve currying with wu.js. Wu.js offers the autoCurry() method that automatically adds currying to a given function, which is more or less what we want.

var curryTest = wu.autoCurry(sumUpTheThree);
curryTest(1)(2)(3);

curryTest(1)()()(2)()(3);

curryTest(1)()()(2)()()(3);

curryTest(1)(2, 3);

curryTest(1, 2, 3);

All of the above will work.

Round Up

This was a basic introduction into partial application and currying in javascript. If you are looking for a library for lazy, functional programming in Javascript checkout wu.js.