In JavaScript, it is possible to partially apply functions (or curry a function).
http://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications
In JavaScript, it is possible to partially apply functions (or curry a function).
http://stackoverflow.com/questions/113780/javascript-curry-what-are-the-practical-applications
function ( | |
a, // the function to curry or partially apply | |
b // placeholder variable for splicing arguments | |
) { | |
b = [].slice.call(arguments,1); // convert arguments to an array | |
return function () { // return a new function which: | |
return a.apply(this, b.concat(b.slice.call(arguments))) // apply the original function with old arguments combined with new arguments | |
} | |
} |
function(a,b){b=[].slice.call(arguments,1);return function(){return a.apply(this,b.concat(b.slice.call(arguments)))}} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Eli Perelman <http://eliperelman.com> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "JavaScriptCurryFunctions140bytes", | |
"description": "Small function to allow the partial application of JS functions.", | |
"keywords": [ | |
"curry", | |
"partial", | |
"application", | |
"javascript", | |
"curried" | |
] | |
} |
<!DOCTYPE html> | |
<title>JavaScript Partial Function Application (Currying)</title> | |
<script> | |
var curry = function(a,b){b=[].slice.call(arguments,1);return function(){return a.apply(this,b.concat(b.slice.call(arguments)))}}; | |
// this function takes whatever arguments are passed and adds them together | |
var adder = function() { | |
var n = 0, args = [].slice.call(arguments); | |
for (var i = 0, len = args.length; i < len; i++) { | |
n += args[i]; | |
} | |
return n; | |
}; | |
// logs: 4 | |
console.log(adder(2,2)); | |
// curry adder for later application | |
var addTwelve = curry(adder, 12); | |
// logs: 15 | |
console.log(addTwelve(3)); | |
// logs: 25 | |
console.log(addTwelve(3,6,4)); | |
</script> |
@jed I have tried for a couple hours to no avail. Function.prototype.bind
is a toughie. This is what I have so far:
Function.prototype.bind=Date.bind||function(a,b,c,d){b=[].slice.call(arguments,1),c=this,d=function(e){e=b.concat(b.slice.call(arguments));if(!(this instanceof d))return c.apply(a,b);c.apply(this,b)},d.prototype = c.prototype;return d}
as a baseline, i think andrea giammarchi's approach is good:
function(a,b,c){b=[c=this].slice.call(arguments,1);return function(){return a.apply(c,b.concat.apply(b,arguments))}}
the hard part is assigning it for bind.
you should try your hand at shimming
Function.prototype.bind
. i tried and couldn't pull it off.