Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
One way to create a curry function. Currying:
module.exports = curry;
function curry (f) {
var arity = f.length;
var params = [];
var end = createEnd(f, arity);
return createCurried(params, arity, end);
function createEnd (f, arity) {
var src = 'return f(';
for (var i = 0; i < arity; i++) {
src += (i ? ', p[' : 'p[') + i + ']';
src += ');';
var endCall = new Function ('f', 'p', src);
return function end (p) {
return endCall(f, p);
function createCurried (collected, arity, end) {
return function () {
var params = concat(collected, arguments);
return params.length < arity
? createCurried(params, arity, end)
: end(params);
function concat (a, b) {
var al = a.length;
var bl = b.length;
var c = new Array(al + bl);
var i;
for (i = 0; i < al; ++i) c[i] = a[i];
for (i = 0; i < bl; ++i) c[i+al] = b[i];
return c;

This comment has been minimized.

Copy link
Owner Author

unscriptable commented Aug 1, 2014

Seems like it'd be pretty fast because it avoids fn.apply(). However, since this this curry() ignores extra arguments, it can't be applied to functions with optional params that aren't reflected in the function's arity (length). :(

We would have to allow devs to supply an optional arity param to curry():

// splice has arity === 2, but has additional optional params
var spliceWithOneInsert = curry(array.splice.bind(array), 3);

This comment has been minimized.

Copy link

briancavalier commented Aug 1, 2014

Really cool. Here's a small variant that uses a dynamic compilation trick in order to give a name to the end function--might help during debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.