 ## ```Currying Video Tutorial ```

In this video we will discover the principle of currying. This principle of functional programming makes it possible to transform a function which expects several arguments into a function with one argument which will return a function for the rest of the arguments.

For example this function:

``````function multiply (a, b, c) {
return a * b * c
}

multiply (1, 2, 3)
``````

Can be transformed in this way:

``````curry (multiply) (1) (2) (3)
``````

It can also be done in reverse by making the first call match the last argument.

``````curryRight (multiply) (3) (2) (1)
``````

## What use?

Currying is not necessarily a reason that we will find systematically but it makes it possible to simplify certain operations.

``````function multiply (a, b) {
return a * b
}

const double = curry (multiply) (2)

(1, 2, 3) .map (double) // Allows to double each value of the array
('1', '23', '4'). Map (curryRight (parseInt, 2) (10)) // Make sure that the parseInt will use a base 10
``````

You can also simplify a function that expects too many arguments.

``````function getPropertyOrDefault (obj, property, defaultValue) {
return obj (property) || defaultValue
}

const getPropertyOrNull = curryRight (getPropertyOrDefault) (null)
const getTotal = curryRight (getPropertyOrDefault) (0) ('total')

getTotal ({a: '3'}) // 0
getTotal ({total: 100}) // 100
``````

## Example of implementation

Now that we have seen the principle, we can wonder how this transformation will work. In JavaScript it is quite simple to implement a currying method based on `apply ()` and `bind ()`. We will allow our functions to accept a second argument to manually specify the number of arguments expected by the function (for example `parseInt.length` will send back `1` therefore we cannot rely only on this property to determine the number of parameters).

``````function curry (func, arity = null) {
return function curried (... args) {
if (args.length> = (arity || func.length)) {
return func.apply (this, args)
}
return curried.bind (this, ... args)
}
}

function curryRight (func, arity = null) {
return function curried (... args) {
if (args.length> = (arity || func.length)) {
return func.apply (this, args)
}
return function (... args2) {
return curried.apply (this, (... args2, ... args))
}
}
}
``````