Functional chains using partial (in JavaScript)

John Reisg posted an interesting post about ultra-chaining. I think the idea is pretty interesting and especially useful for effects. I have another solution for this problem.

Currently to chain things in JQuery you do it via callbacks:

jQuery("div").hide("slow", function(){
  jQuery(this)
    .addClass("done")
    .find("span")
      .addClass("done")
    .end()
    .show("slow", function(){
      jQuery(this).removeClass("done");
    });
});

The proposed optimizations is to use an explicit chain function:

jQuery("div").chain("hide", "slow")
  .addClass("done")
  .find("span")
    .addClass("done")
  .end()
  .chain("show", "slow")
    .removeClass("done")
  .end()
.end();

I think one could get the same effect by using partial evaluation:

chain(
    $p(hide, elm, 'slow'),
    $p(addClass, elm, 'done'),
    $p(addClass, $gc(elm, 'span'), 'done'),
    $p(chain,
        $p(show, elm, 'slow'),
        $p(removeClass, elm, 'done')
    )
)

//$p = partial
//$gc = getChild

I think chains implemented via partial evaluation are more readable and it does not use "dirty" tricks such as passing method names as strings. The implementation of JQuery's proposal will be pretty hard while chains using partial evaluation are pretty trivial to implement.

Partial can be implemented in following way:

function partial(fn) {
    var args = Array.prototype.slice.call(arguments);
    args.shift();
    return function() {
        var new_args = Array.prototype.slice.call(arguments);
        args = args.concat(new_args);
        return fn.apply(window, args);
    }
}
$p = partial;

If you haven't used partial before, here is a simple example how it works:

function add(a, b) {
   return a+b;
}

var adder_2 = partial(add, 2); 
adder_2(5); //will evaluate to 7 :)
Code · Code improvement · JavaScript 15. Oct 2008
© Amir Salihefendic. Powered by Skeletonz.