##
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))
}
}
}
```