# Understanding JavaScript Currying with a practical use case

## Most used functional programming design pattern

# The problem

Given a comma separated values string, aka “.csv”, with numbers in decimal system — base 10. Get a parsed array of integers.

Sounds like a good Interview question!

`const input = '1, 2, 3, 4, 5'`

`function parseCSVNumbers(csvString){`

// some logic :)

}

`const output = [1, 2, 3, 4, 5]`

# A common solution

- Split csv input string, into an array of strings.
- Parse each string from the array.
- Return an array with the parsed numbers.

`function parseCSVNumbers(csvString) {`

const stringNumbers = csvString.split(',')

const parsedNumbers = stringNumbers.map(stringNumber => parseInt(stringNumber))

return parsedNumbers

}

Interview score: not bad…

This is one of the most used and simple **currying **in everyday JavaScript codes— even though it’s not commonly recognized as so:

`stringNumber => parseInt(stringNumber)`

With this extra explanation, our score was improved to good.

In step to really understand why this is in fact a valid currying case, let’s rewrite this callback as an ordinary JavaScript function:

`function oneParameterParseInt (string) { `

return parseInt(string)

}

The prefix `oneParameter`

was added on purpose to emphasize what this function really does — calls JavaScript standard built-in object `parseInt`

with strictly one parameter, and thus ensuring a radix/base of 10 parsing.

In other words, the arity of `parseInt`

was reduced from 2 to 1.

# Currying by hand solution

Instead of limiting `parseInt`

to one parameter, let’s curry it properly:

`function curriedParseInt(string) { `

return function(radix) {

return parseInt(string, radix)

}

First call of `curriedParseInt`

which takes a string parameter, will return a function which takes a `radix`

parameter, which finally will call `parseInt`

with both parameters and return its result.

`const parseOne = curriedParseInt('1')`

const parsedNumber = parseOne(10)

or

`const parsedNumber = curriedParseInt('1')(10)`

Only our conceptual interview score was improved.

Well, is it possible to improve the solution using this curried version of `parseInt`

?

Short answer is **no**, because it’s still needed to explicitly provide the radix for each string value from the csv.

# Invert parameters order

As the csv has the same radix for all its values, it’ll be useful to use the radix once and then to have a function to parse each value — a callback for the map.

This can be achieved by simply inverting the parameters order as follow:

`function curryiedInvertedParseInt(radix) { `

return function(string) {

return parseInt(string, radix)

}

Similarly, first call of `curriedInvertedParseInt`

which takes a `radix`

parameter, will return a function which takes a string parameter, which finally will call `parseInt`

with both parameters and return its result.

Finally it’s possible to improve the original solution as follow:

function parseCSVNumbers(csvString, base=10) {

const parse = radix => string => parseInt(string, radix) const stringNumbers = csvString.split(',')

const parsedNumbers = stringNumbers.map(parse(base))

return parsedNumbers

}

or

function parseCSVNumbers(csvString, base=10) {

const parse = radix => string => parseInt(string, radix)

const parseDecimal = parse(base) const stringNumbers = csvString.split(',')

const parsedNumbers = stringNumbers.map(parseDecimal)

return parsedNumbers

}

Our practical interview score has increased. Now we are very good!

Further improvements will require more functional base elements such as pipeline, compose or flow. Good news is there is a proposal for it https://github.com/tc39/proposal-pipeline-operator

# A more generic currying solution

To reinforce currying concept, let’s code a generic function which takes any function and returns a curried version of it.

In the following recursive solution, bind is used — standard built-in function prototype method to set `this`

and to add preceding parameters.

`function curry(fn) {`

if (fn.length === 0) {

return fn()

}

return function bindOneParam (p) {

return curry(fn.bind(null, p))

}

}

A recursive function is a function that calls itself during its execution.

It’s very important to have a stop condition in recursion, which in this case is to have no parameters left from `fn`

— parameters length equal to 0.

This `curry`

version will extract one parameter at a time from `fn`

parameters, and return a new function which takes the extracted parameter as an input and binds it to `fn`

and call `curry`

again, but this time `fn`

has one less parameter. Last call will simply return `fn`

execution result.

Take your time to digest all these concepts.

Now it’s time to see how curry really works with the arity 2 — two arguments, `parseInt`

standard function:

`const stringParam = curry(parseInt)`

as `parseInt.length`

is not 0 , `curry`

will return `stringParam`

which is basically:

`function stringParam (string) {`

return curry(parseInt.bind(null, string))

}

Calling `stringParam`

with a string parameter:

`const radixParam = stringParam('1234')`

Will first evaluate the inner `bind`

function, which will extract one parameter from `parseInt`

and return a new function with ‘1234’ as a preceding argument:

`const innerBind = parseInt.bind(null, '1234')`

Then `curry(innerBind)`

, which is the first recursive call to `curry`

, but this time with the arity 1 `innerBind`

function instead of `parseInt`

, this will similarly return:

`function radixParam (radix) {`

return curry(innerBind.bind(null, radix))

}

Analog to `stringParam`

, calling `radixParam`

with a `radix`

parameter:

`const decimalNumber = radixParam(10)`

Will first evaluate the last `bind`

function, which will extract one parameter from `innerBind`

and return a new function with 10 as a preceding argument:

`const lastBind = innerBind.bind(null, 10)`

Then `curry(lastBind)`

, the second recursive call to `curry`

, but this time with the arity 0 `lastBind`

function instead of `innerBind`

, this will end the recursion, execute `lastBind`

and return its value.

If you still here, congratulation, our interview score now is excellent!

Curring is commonly used in modern JavaScript code, at least in its simpliest form, and combining it with pipe allow for a clean, readible and powerful functional programming — even in JavaScript.

Last interview question, why can’t we simply do this, without currying at all:

`['1', '2', '3', '4'].map(parseInt)`

?