Extending Currying: Partial Functions in Javascript
- by kerry
Last week I posted about function currying in javascript. This week I am taking it a step further by adding the ability to call partial functions.
Suppose we have a graphing application that will pull data via Ajax and perform some calculation to update a graph. Using a method with the signature ‘updateGraph(id,value)’.
To do this, we have do something like this:
1: for(var i=0;i<objects.length;i++) {
2: Ajax.request('/some/data',{id:objects[i].id},function(json) {
3: updateGraph(json.id, json.value);
4: }
5: }
This works fine. But, using this method we need to return the id in the json response from the server. This works fine, but is not that elegant and increase network traffic.
Using partial function currying we can bind the id parameter and add the second parameter later (when returning from the asynchronous call). To do this, we will need the updated curry method. I have added support for sending additional parameters at runtime for curried methods.
1: Function.prototype.curry = function(scope) {
2: scope = scope || window
3: var args = [];
4: for (var i=1, len = arguments.length; i < len; ++i) {
5: args.push(arguments[i]);
6: }
7: var m = this;
8: return function() {
9: for (var i=0, len = arguments.length; i < len; ++i) {
10: args.push(arguments[i]);
11: }
12: return m.apply(scope, args);
13: };
14: }
To partially curry this method we will call the curry method with the id parameter, then the request will callback on it with just the value. Any additional parameters are appended to the method call.
1: for(var i=0;i<objects.length;i++) {
2: var id=objects[i].id;
3: Ajax.request('/some/data',{id: id}, updateGraph.curry(id));
4: }
As you can see, partial currying gives is a very useful tool and this simple method should be a part of every developer’s toolbox.