Skip to content

Instantly share code, notes, and snippets.

@ELLIOTTCABLE
Created December 21, 2012 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ELLIOTTCABLE/4350333 to your computer and use it in GitHub Desktop.
Save ELLIOTTCABLE/4350333 to your computer and use it in GitHub Desktop.
An implementation of `<func>.curry()`, as an alternative to `Function..bind()` that: 1. preserves `toString()`, 2. maintains the `.length` of the original, minus progressively curried-in arguments, 3. doesn't require you to stomp on the callee's `this` as `bind()` does.
// Would prefer to use an actual Function-subclass a lá `from`, so that I don't have to manually
// attach a .toString() to each instance; but this will do for the moment.
// FIXME: Will currently error out if you curry in more arguments than the function needs
define(Function.prototype, 'curry', function(){ var that = this
, curried = [].slice.call(arguments)
, uncurried = Array(++that.length - curried.length).join('_').split('')
, eval = GLOBAL.eval // Must be referenced as `eval` <http://es5.github.com/#x15.1.2.1.1>
, result = eval("(function("+uncurried.join(', ')+"){"
+"return that.apply(typeof bound === 'object'" +"\n"
+" || typeof bound === 'function'? bound:this" +"\n"
+" , curried.concat([].slice.call(arguments))) })" +"\n")
, bound
result.bind = function(){} // NYI
result.toString = that.toString.bind(that)
result.final = that.final || that
return result })
@Gozala
Copy link

Gozala commented Dec 22, 2012

Eval destroys JIT optimizations, I think it would be better to use Function in your case.

@ELLIOTTCABLE
Copy link
Author

@Gozala I originally was using Function; but in this particular case, it doesn't work out so well. I need to get some of those function-locals (obv. curried, bound, etceteras) into the constructed function-body; I could do so with a fairly hacky bind() approach, but the entire point of this implementation was to attempt to avoid bind().

I might benchmark it later, depending on how much it affects my particular use-case, and re-write it.

(Of note: is the Function constructor actually faster than a locally-evoked eval()? Do you have a link to some benchmarks, or a discussion thereof?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment