# Partial application

I recently bought a paperback version of Kyle Simpson's Functional-Light Javascript and decided to wrap up one of the main concepts from the first few chapters: partial application.

## What is partial application?

With partial application, we fix certain arguments to a function. One contrived example revolves around a mathematical sum function:

``````
function sum(a, b) {
return a + b;
}

const sumThree = sum.bind(null, 3);

sumThree(1);    // 4
sumThree(5);    // 8

const sumFour = sum.bind(null, 4);

sumFour(1);    // 5
sumFour(5);    // 9
```
```

But how does this actually work? To answer that question, we need to have a closer look at Javascript functions.

## Function prototype methods

Every Javascript function is actually a Function object.

Hence, a Javascript function comes with its own set of prototype methods:

• `call()`
• `bind()`
• `apply()`
• `toString()`

In the example above, we called the prototype method `bind` on the function `sum` in order to create the partially applied functions `sumThree` and `sumFour`.

Looking at the signature for `bind`, it is variadic which means it accepts an indefinite number of arguments. The first parameter is named `thisArg` and represents the value to be passed as the `this` parameter.

Consider:

``````
const randomObject = {
a: 1,
};

function sum(x) {
return this.a + x;
}

const sumThree = sum.bind(randomObject, 3);

sumThree();    // 4
```
```

In the (again: contrived) example above, the `this` argument of `sum` was bound to `randomObject` for `sumThree`. While in the first example above, we passed `null` as the first argument because we did not access `this` inside our function body.

## Pop quiz

Pop quiz: can you guess what happens if copy the previous example but instead assign an empty object to `randomObject`?

``````
const randomObject = {};

// same code as before ...
```
```

``````
sumThree();    // NaN
```
```

Why is that? Because `this.a` equals `undefined` when `this` is bound to `randomObject`, the expression to be evaluated is `undefined + 3`.

If you re-read the type coercion rules, for example in You Don't Know JS Yet: Types & Grammar, you will see that in expressions with mathematical operators (such as `+`), both operands are coerced to a number.

That means, the expression to be evaluated after the type coercion is `Number(undefined) + 3`. And `Number(undefined)` equals `NaN`, which leaves `NaN + 3` and that also evaluates to `NaN`.

## Back to partial application

While `bind` is thus undoubtedly the native way for applying (no pun intended) partial application, I will have to agree with the premise in Functional-Light Javascript: I don't see a use case for both setting the `this` argument while at the same time partially applying other arguments.

At the time when the specifications for `bind` were created, the goal was likely to consider `this` as just another argument to a function. Thus, having one function to bind all arguments might have made theoretical sense. But practically, it is hard to even come up with a contrived example.

If you tried to make the example above more realistic, you would either pass in the object (or some of its properties) as an argument to the function, or you could make the `x` parameter accessible as a property on `randomObject`. Both options would forgo passing in an actual object as the `this` argument to `bind`, while at the same time passing in one or more arguments to be partially applied.

## Ramda

Let's try to swap `bind` with a method from one of the popular functional programming libraries: Ramda.

We can re-create the first example as:

``````
const R = require('ramda');

function sum(a, b) {
return a + b;
}

const sumThree = R.partial(sum, );

sumThree(1);    // 4
sumThree(5);    // 8
```
```

## Fixing multiple arguments

Partial application is not constrained to a single argument. The signature for `bind` accepts an indefinite number of arguments:

``````
function sum(a, b, c) {
return a + b + c;
}

const sumThreeAndTwo = sum.bind(null, 3, 2);

sumThreeAndTwo(1);    // 6
sumThreeAndTwo(5);    // 10
```
```

Ramda does things a little differently, where the arguments, regardless of their number, should always be passed as an array.

``````
const R = require('ramda');

function sum(a, b, c) {
return a + b + c;
}

const sumThreeAndTwo = R.partial(sum, [3, 2]);

sumThreeAndTwo(1);    // 6
sumThreeAndTwo(5);    // 10
```
```

I find this syntax from Ramda a lot cleaner than with `sum.bind(null, 3, 2)` as `partial` immediately indicates what we are trying to achieve here. Of course, that comes with the overhead cost of adding a new dependency to your project. Alternatively, you could come up with your own implementation while keeping the same function signature.

## Use cases

We've now seen what partial application is, how you can apply it but the question remains: what is it useful for? I've tried to find specific cases

• For my IBAN application, I could use it to create a partially applied function for converting strings to the BigInt type using `BigInt(parseInt(...))` where the radix is always 10. In that case, I will have to use `partialRight` though, because otherwise `partial` always fixes the first argument(s), which is not the radix but the string to be parsed. While `partialRight` always fixes the last argument.
• In my daytime job, we frequently use helper functions to convert values to another unit. Put simply, these helper functions have 2 parameters: `value` and `unit`. Instead of always passing an argument for `unit`, we could create separate functions where that unit is fixed, but we can still pass an argument for `value`. This also plays into the argument that functions with a lower arity (the number of parameters a function accepts) can easily be composed from those with a higher arity, while often being easier to read and comprehend.

## Conclusion

While I've obviously barely scratched the surface of partial application, this article feels like a good summary of the basics. We've seen what partial application is, how to use it (either with `bind` or with Ramda), and which use cases there are.