JavaScript Partials

In a previous post I introduced the curry function. To recap, currying creates a new function with the first n arguments pre-assigned:-

var subtract = function(a,b) {
    return a - b;

var subtractFrom8 = subtract.curry(8);

subtractFrom8(2); //6

Currying is an expressive and compact alternative to manually wrapping anonymous functions. I use it a lot. But sometimes its not enough – the problem is you can only pre-assign the first n arguments. What if we wanted to make a function and pre-assign the rightmost argument, or maybe the middle two? Enter partial:-

var subtract5 = subtract.partial(___,5);

subtract5(13); //8;

I’ve augmented the Function prototype with an implementation of partial. I’m using a global variable, ___ (three underscores) to indicate an argument placeholder. If you’re nervous about name clashes in the global scope you may want to define a Partial object and set a property on it (e.g. Partial.___);

window.___ = {}; //argument placeholder

Function.prototype.partial = function() {
    if (arguments.length<1) {
        return this; //nothing to pre-assign - return the function as is
    var __method = this;
    var args = arguments;
    return function() {
        //build up new arg list, for placeholders use current arg, otherwise copy original args
        var argIndex = 0, myArgs = [];
        for (var i = 0; i < args.length; i++) {
            myArgs[i] = window.___==args[i] ? arguments[argIndex++] : args[i];
        return __method.apply(this, myArgs);

The returned function iterates through the arguments we passed to partial, and looks for any placeholders. When it finds one it injects the next runtime argument in its place. With luck we now have the full set of arguments, a hybrid of pre-assigned and runtime args. (If there are fewer runtime arguments than placeholders, the jilted placeholders get replaced by undefined.)

The partial function offers a superset of the functionality provided by curry so theoretically we could drop curry from our library, However when you only need to replace the first n arguments, using curry means you don’t need specify placeholders:-

//curry using curry
var atLeast10 = Math.max.curry(10);

//curry using partial
var atLeast10 = Math.max.partial(10,___);

Now let’s give our new partial function a workout:-

Define a remove function:-

String.prototype.remove = String.prototype.replace.partial(___,'');

"12654I 2am2 13not12 3a45 3number3 453".remove(/\d/gi); //"I am not a number"

Get the cube root of anything…

var unCube = Math.pow.partial(___,1/3);

unCube(27); //3
unCube(15); //2.46621207433047

Call me later…

var later = timeOut.partial(___,1000);

later(alert.curry("here I am!"));//... ... "here I am!"

An intuitive variant on parseInt…

parseInt("035"); //29 ( literals starting with 0 assumed to be base 8 )

var toInt = parseInt.partial(___,10); //specifies base 10
toInt("035"); //35

Using jQuery’s array map function, a utility to increment each member by 1…

var incrementAll =,function(x) {return x+1});

incrementAll([0,2,4,6,8]); //[1,3,5,7,9];

The partial function comes with an interesting side effect: The returned function will only use the first n arguments passed to it, where n is the number of placeholders that were passed to partial. Thus we can strictly limit the number of arguments visible to a function:-

var a = [1,2,3,4];
var b = [5,6,7,8];

//regular push adds all supplied arguments...
Array.prototype.push.apply(a,b); //a = [1,2,3,4,5,6,7,8];

//using partial we can create a pushFirst that will ignore surplus args....
var pushFirst = Array.prototype.push.partial(___);
pushFirst.apply(a,b); //a = [1,2,3,4,5]

16 thoughts on “JavaScript Partials

  1. Hey Angus,

    Good post! I like how we both use three underscores; great minds, no?

    However, I think you have two copies of the post concatenated… WordPress issue?

    I’m working on a rant myself about self invoking functions and how unnecessary they should be, not because of JS’s global scope, but because this is exactly the type of thing that the evaluator should expand for us. We are expanding Scheme’s “let” expression by hand every time we use the self invoking function pattern!

    Let expressions are derived expressions, because

    (let ((var1 exp1) … (varn expn))

    is equivalent to

    ((lambda (var1 … varn)

    Brenden Eich mentions how he wants to introduce macros to EMCAScript in Coders At Work and this is a perfect example of why we need them!

    1. >>However, I think you have two copies of the post concatenated… WordPress issue?

      No, me issue ;-)Thanks for pointing it out!

      Talking of me-issues, I’m having trouble drawing the connection between self invoking functions (which I admit a certain addiction to) and lack of evaluator expansion. Got a link to your rant? And to Eich on macros? Thanks….

      1. I don’t know if you know any Scheme or Lisp at all, but (in Scheme, at least) the “let” expression is syntactic sugar — a macro — that expands in to a self invoking function. Creating a new lexical scope this way is such a common pattern that it deserves its own syntax. What I meant was that if javascript had macros like Scheme, we could define this syntax ourselves, and the evaluator would expand it for us. Instead, we are expanding this hypothetical macro by hand every time. If I were to translate to semi JS syntax, it would look something like this:

        let (foo = 5, bar = 3 * 3) {

        would be equivalent to

        (function (foo, bar) {
        }(5, 3 * 3);

        Of course, “let” would be off limits for JS since Mozilla seems to be introducing a completely different use for “let” in javascript 1.7 or 1.8 or something.

        I don’t have a link to the quote of Eich, unfortunately. If you have a copy of Coders At Work by Peter Seibel, he has an interview with Eich which is where the quote is from. It is on page 144:

        “We were concerned that if we went off to do macros we were doing research, and if we were doing research we were not going to have Microsoft engaged and we were not going to be putting competitive pressure on them. So macros have had to wait. I’m fine with that so long as we do the right automated grammar checks and we do make sure we can recast all the sugar as macros. But in the meantime, there’s no reason to starve users for sugar. It doesn’t rot their teeth and it helps them avoid mistakes.”

        There’s a whole lot more than that, but I’m not going to type up the whole chapter :) You should really get the book, it is fantastic.

        PS Is there a way to format code in the comments? Looks like my indentation has been getting screwed up…

      2. Thanks this is great stuff. This is probably naive of me, but why do we ever need to pass anything to self-invoking functions – since by definition they are one time things, what is there to parameterize?

        My two cents…we’re forced into using self-invoking functions because we need closures (not functions). I’d be happy if ECMA introduced a closure keyword as an alternative

        For code formatting you can wrap with


        . I updated your last comment with formatting…

      3. Exactly! Because we need closures! Continuing with the hypothetical “let” sugar:

        var accumulator = let (n = 0) {
            return function (i) {
                return n += i;
        accumulator(1) // 1
        accumulator(1) // 2
        accumulator(3) // 5

        Now the accumulator is the only thing that has access to the scope with the “n” binding.

        Its a little funky because you have to explicitly return values in javascript, where in more functional languages like Scheme it is implicit, but it is a very nice pattern.

        Also, consider the following:

        var MODULE = let (globals = window) {
            var myLocal = "private to this scope!";
            return {
                sharePrivate: function () { alert(myLocal); }

        For more on when its nice to make new bindings in a closure, check this out:

      4. OK I like the last example. It basically does for the module patten what partial does for wrapping anonymous functions. i.e. its concise and expressive
        Now I’m getting your drift. :-)

        Your other example could be equally succinctly written in the conventional module pattern

        var accumulator = (function() {
            var n=0;
            return function (i) {
                return n += i;
        accumulator(1) // 1
        accumulator(1) // 2
        accumulator(3) // 5

        well almost anyway – but then we are in self invoking function mode and I guess the overriding issue is that its not semantic

  2. Angus,

    Interesting post. However, there’s a problem with your implementation, in that the placeholders in args get replaced the first time you call the partial, and so on subsequent calls no replacement occurs. So the partial only works correctly the first time. In general, it’s an interesting approach.

  3. would probably suggest converting the inner arguments to an array, then appending anything that is left to the end. this way you could do something like..

    var go = doSomething.partial(___, “go”);
    go(“a”, otherArg)

    that would actually call doSomething(“a”, “go”, otherArg)

    1. Hi Michael, yeah that would be good if you wanted to allow unlimited args at runtime – but in one example I demoed how the current impl could be de used to intentionally ignore extra args. It boils down to how you want the function to work

      var a = [1,2,3,4];
      var b = [5,6,7,8];
      //regular push adds all supplied arguments...
      Array.prototype.push.apply(a,b); //a = [1,2,3,4,5,6,7,8];
      //using partial we can create a pushFirst that will ignore surplus args....
      var pushFirst = Array.prototype.push.partial(___);
      pushFirst.apply(a,b); //a = [1,2,3,4,5]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s