Created
December 21, 2012 02:43
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 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
Eval destroys JIT optimizations, I think it would be better to use
Function
in your case.