If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Currying in JS

I don't know how many of you are aware that ECMAScript can be used as a functional language (I suspect the definition of a functional language would probably increase that number), but I've had a fair few of people asking me on IRC how currying is accomplished in Javascript, so I thought I'd share it here in the hopes that it might reach a few of them, and maybe useful to others as well:

The function takes three arguments, the latter two of which are optional: the function to curry, the number of arguments to take before applying them to the function, and the arguments to store initially.

Currying allows arguments to be passed to a function one at a time, each applied argument returning either a function that can apply the next argument or a the result of the function with the given arguments, if enough arguments have been given. ECMAScript's variable arguments also allow, unusually, for a variable number of arguments to be passed to each function. For example, say we had a very simple function:

... but this returns 0 -- there are no formal parameters defined, so the function is called immediately. Attempts at further currying would, of course, fail with an error: currying a number doesn't make much sense! Instead, we can use the optional second argument:

Code:

curry(madd, 4)(1)(2)(3)(4); // 10 (1 + 2 + 3 + 4)

The optional third argument is actually mostly there for internal use (it's used to pass on the current arguments for the next internal call to curry()) but it can sometimes be convenient to the user as well: curry(add, null, [1, 2, 3]) is the same as curry(add)(1, 2, 3).

Applied wisely, currying can greatly improve readability, flexibility, and code size of your scripts, since it can be used in a lot of situations where people would normally define a full-blown function.

Not really I had bookmarked this one sometimes back and thought of providing this for other users who can continue the reading after your post a bit more. I feel that most of them addressing this as closures then currying..

It will not work properly with varargs because the point-free feature would require backtracking, which has two problems:
1) JS is not referentially transparent.
2) Recursive curried functions could take non-polynomial in time. (Or at least I couldn't figure out a way to do it in polynomial time.)

Should a function have varargs, it will treat the function as if it did not have any.

Well, it would have to be with a limitation that only the last function down the apply chain (hmm I like that name more than curryApply) can have varargs.

Basically you would continually apply n arguments to the function, where n is it's arity. If the result is a function, repeat with the rest of the arguments until you run out of arguments or a non-function value is returned. In the case you run out of arguments, you're done. Otherwise, backtrack one step back to get the previous function and the old set of arguments. Now apply all the arguments to the function.

EDIT:
Just looking at my code in the above post, I would probably move chainApply (curryApply) outside the curry closure because it's useful. Also, the inner function in the compose method does not need to be curried; the outer curry handles should handle it nicely.

Also for those who don't know better, the definition I gave for map is to demonstrate point-free code in javascript. I wouldn't recommend implementing such a trivial function in this manner, especially the cons function.