Skip to content

Instantly share code, notes, and snippets.

@harmenjanssen
Last active September 20, 2017 20:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harmenjanssen/09ca006453a7bdf08b4802c4f1244670 to your computer and use it in GitHub Desktop.
Save harmenjanssen/09ca006453a7bdf08b4802c4f1244670 to your computer and use it in GitHub Desktop.
/**
* Ha! I totally fucked up. I noticed after publishing this, so instead of quietly updating this I will
* add a bit of educational text.
*
* The function below, curry_bodged, makes the mistake of saving the args in lexical scope, resulting in
* an ever-expanding list of arguments. Every time you call the curried function the arguments are added to
* the same list, and the actual applied function will probably re-use the same arguments from the first time.
*
* Example with the `addThree` function below:
* addThree(1, 2, 3) // 6, args = [1, 2, 3]
* addThree(42, 100, 48) // also 6, because args = [1, 2, 3, 42, 100, 48]
*
* Well. Anyways. The curry function below is correct and actually much more elegant.
*
* Oh, one more thing: since this curry() function uses Function.bind(null) it will totally screw up functions
* using `this`.
* But I never use `this` so I don't care for the moment. Bye now, gotta run!
*/
const curry = fn => {
const arity = fn.length;
return (...args) => args.length < arity
? curry(fn.bind(null, ...args))
: fn(...args);
};
// usage:
const addThree = curry((a, b, c) => a + b + c);
// addThree(1, 2, 3) === addThree(1)(2)(3) === addThree(1, 2)(3) === addThree(1)(2, 3) === 6
const curry_bodged = fn => {
let args = [];
const arity = fn.length;
return function inner(...xs) {
args = args.concat(xs);
if (args.length < arity) {
return inner;
}
return fn(...args);
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment