# JavaScript Currying: Its really just reduce over variadic input. …and its not that hard.

Currying is a technique of converting a function that takes n-number parameters to an n-chain of functions that takes one parameter at a time until all n-number parameters are collected and the function is evaluated. Consider the functions `sum2` and `sum3`:

`const sum2 = (a,b) => a + bconst sum3 = (a,b,c) => a + b + c`

We could define them in curried form by writing them like this:

`const sum2 = a => b => a + bconst sum3 = a => b => c => a + b + c`

A practical reason to favor curried form occurs in certain situations where you want automatic partial applications. Consider the two increment functions. The first `incrA` where it is built off of curried form`sum2` function and the second where `incrB` it is built off of a traditional (also called tupled form) `sum2`:

`// if sum2 is in curried formconst incrA = sum2(1)// if sum2 is in tupled formconst incrB = (b) => sum2(1, b)`

The latter requires some boilerplate while the former reads a little bit clearer. Writing a function that takes a 2-tuple or 3-tuple input in a curried form is relatively trivial. However as the number or parameters increase writing in curried form can be a bit gnarly. We can solve this by creating a magic function that does this for us.

Consider a very specific function `curry2` that takes a 2-tuple and converts it to its curried form:

`const curry2 = f => a => b => f(a, b)`

`curry2` takes as input a function `f` (e.g. sum2) and then each individual argument `a` & `b` and when it has both of them invokes the captured function `f `with those parameters.

`const sum2Tupled = (a,b) => a + bconst sum2Curried = curry2(sum2Tupled)`

While we can work on a number of utility functions curry2, curry3, curry4 etc. However there is a slightly better way — we can leverage

• reduce
• and papply

Lets take this backwards. `papply` is a utility function that takes a function and an input and partially applies that input to that function. The effect is similar to that of a function defined in a curried form, but lacking somewhat in syntactic sugar.

`// consider sum2 defined in tupled formconst incr = papply(sum2, 1)`

This utility (papply) is fairly easy to write:

`const papply = (f, x) => f.bind(null, x)`

The next step is defining `reduce`. As we know (article on reduce) that `reduce` has the intent of aggregating a list into a single value through a self-provided reducing function:

`const head = xs => xsconst tail = xs => xs.slice(1)const reduce = (f, agg, list) =>    (list.length == 0) ?        agg :        reduce(f, f(agg, head(list)), tail(list)) ;`

To define the magical `curry` function we need to combine the papply with reduce and the magical spread operator:

`const curry = f =>    (f.length == 0) ?        f() :        (...xs) => curry(reduce(papply, f, xs)) ;`

`curry` takes a function `f`. If that functions has had all of its arguments bound, it is invoked and the result are returned. If that function (`f`) still has free arguments `curry` then returns an anonymous function that takes any number of inputs, captured as an array via spread operator `…xs`. Those inputs are then partially applied onto `f` via `papply` by `reduce`. We then `curry` that result which starts the entire process over (i.e. check to see if all of the arguments are bound).

To remind ourselves of how reduce works to sum lists:

`const add2 = (a,b) => a + b// using a list processing libraryconst sumList = list => reduce(add2, 0, list)`

reduce takes something that combines two objects — in the case of `sumList` this is `add2`. The combiner takes these objects in a particular order. The first object is the running aggregate. The second object is the next thing to be applied to that aggregate. `Reduce` also takes an initial value — in the case of `sumList` this is `0`. Lastly it takes the list `list`.

Applying this thought process to `curry:`

`reduce(papply, f, xs)`

The inital value is the captured function `f`; In this case it has free parameters. The combining function here is `papply` which creates a new function by taking a function (the running aggregate) and any one parameter and partially applying it. `reduce` repeats this process for every item in the list `xs`.

We can then apply this version of curry to any tupled/traditionally defined function. But please leverage a version from either Ramda or Sanctuary. My implementation doesn’t handle:

1. the attempt to curry a function that doesn’t take input
2. the application of more parameters than the captured function intends to take