How to make functions partially applicable in JavaScript
Tags: javascript, functional
Published: 2018-03-07 14:16:40

---
title: How to make functions partially applicable in JavaScript
published: true
description: Enable partial function application in JavaScript
tags: javascript, fp
---

> Update: [Learn how to type PartiallyApplicable in TypeScript](https://dev.to/ycmjason/typing-partially-applicable-functions-1oa4)

## TL; DR

```js
const enablePartialApplication = (fn) => (...args) => {
	if (args.length >= fn.length) return fn(...args);
	return enablePartialApplication(fn.bind(null, ...args));
};
```

## What is partial function application?
Partial function application describes the ability to partially apply some arguments to a function. Sounds abstract? Let's look at some example.

Let's say we have a function `add` which simply adds two numbers:

```javascript
const add = (x, y) => x + y;
add(3, 5); // 8
```
If we only supply one argument, the result yields to `NaN`.
```js
add(3) // basically equivalent to: add(3, undefined)
// -> 3 + undefined
// -> NaN
```
Pretty straightforward?

Some functional programming languages would handles this differently however. For example, if Haskell were to handle `add(3)`, instead of executing the function body `x + y`, it will do something like the following:

```js
// let's pretend haskell is running the following JavaScript
const addThreeTo = add(3);
// addThreeTo is basically the function: (y) => 2 + y
addThreeTo(5); // 8
// or simply
add(3)(5); // 8

// but we could still do
add(3, 5); // 8
```

Notice how we supply the second argument `5` by doing `addThreeTo(5)`. 

Haskell detects the number of arguments supplied. When it is less than what is expected in the function definition, instead of executing the function body, it returns another function that accepts the remaining arguments. This is called partial function application. 

Okay. That's quite cool. But why do we need this? Well you don't. But it is something very convenient to have.

Imagine having a list of numbers and we wish to add `5` to each of them, without partial function application, we have to wrap an arrow function around `add`.

```javascript
const add = (x, y) => x + y;
[1, 2, 3, 4, 5, 6].map(i => add(5, i));
```

However, with partial function application, we could do something like:

```javascript
// let's pretend haskell is running the following JavaScript
const add = (x, y) => x + y;
[1, 2, 3, 4, 5, 6].map(add(5));
```
### Arguments fixing

Partial function application can also be thought of as fixing arguments. 

```js
// let's pretend haskell is running the following JavaScript
const fn = (x, y, z) => (x * y) / z;
const fnFixedX = fn(3); // fixes x to 3: (y, z) => (3 * y) / z
fnFixedX(2, 1); // (3 * 2) / 1 -> 6
```

Or we could also fix `x` and `y` altogether.
```js
// let's pretend haskell is running the following JavaScript
const fn = (x, y, z) => (x * y) / z;
const fnFixedXY = fn(3, 2); // fixes x to 3: (z) => (3 * 2) / z
fnFixedXY(1); // (3 * 2) / 1 -> 6
```

I hope you have understood what partial function application is by now. If not, read again before continuing.

## Implementation
In the previous examples, we pretend that haskell is running the JavaScript in order to illustrate what partial function application is. Now can we actually implement something to enable partial function application in JavaScript? Yes we could!

Let's define a function `enablePartialApplication(fn)` which would return a function that we could use partial function application.

What we want to achieve:
```js
const sum = enablePartialApplication((x, y) => x + y);
const sum3 = sum(3);
sum3(10); // 13
sum(3, 5); // 8
sum(3)(4); // 7
```

Another example:
```js
const fn = enablePartialApplication((x, y, z) => (x * y) / z);
fn(3, 2, 1); // (3 * 2) / 1 -> 6
fn(3, 2)(1); // 6
fn(3)(2, 1); // 6
fn(3)(2)(1); // 6
```

### Skeleton
The function input and output are obvious, so we could sketch the skeleton of our function:
```js
const enablePartialApplication = (fn) => {
	return () => {

	};
};
```


### Looking at the arguments
As I mention earlier, Haskell look at 1) the number of arguments passed in and 2) the number of arguments expected by the definition of the function to decide whether partial application is needed.

The first one is simple, we can just use the rest operator and take in the arguments as a list, then do `.length()` on it.

```js
const enablePartialApplication = (fn) => {
	return (...args) => { // use rest operator to take arguments as a list
		args.length // number of arguments passed in
	};
};
```

The second one is also not that hard, we could use `Function.length`. See [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length) for the documentation.


```js
const enablePartialApplication = (fn) => {
	return (...args) => {
		args.length // number of arguments passed in
		fn.length // number of arguments expected by fn
	};
};
```

We know that it is a partial function application if `args.length < fn.length`, otherwise, i.e. `args.length >= fn.length`, it would just be a simple function invocation. So let's put this into our function:

```js
const enablePartialApplication = (fn) => {
	return (...args) => {
		if (args.length >= fn.length) return fn(...args); // function invocation
		// partial function application here
	};
};
```

### Fixing arguments with `Function.prototype.bind`
Recall the argument fixing analogy, does it remind you of some functions in JavaScript? Yes! `Function.prototype.bind`!  We could fix arguments of a function with it!

```javascript
const add = (x, y) => x + y;
const add3 = add.bind(null, 3); // the first argument is the thisArg
add3(5); // 8
add3.length; // 1
```

We could simply bind the input `args` to `fn` so that the bound function would expect the remaining arguments.

```js
const enablePartialApplication = (fn) => {
	return (...args) => {
		if (args.length >= fn.length) return fn(...args);
		return fn.bind(null, ...args); // use Function.prototype.bind to fix arguments
	};
};
```

This implementation would allow us to do the following:
```js
const sum = enablePartialApplication((x, y) => x + y);
const sum3 = sum(3);
sum3(10); // 13
sum(3, 5); // 8
sum(3)(4); // 7

const fn = enablePartialApplication((x, y, z) => (x * y) / z);
fn(3, 2, 1); // (3 * 2) / 1 -> 6
fn(3, 2)(1); // 6
fn(3)(2, 1); // 6
```

Awesome! However, the returned bound function do not support partial application. So the following would not work

```js
const fn = enablePartialApplication((x, y, z) => (x * y) / z);
fn(3)(2)(1); // Trying to partially apply the function: fn(3)
// -> ((y, z) => (3 * y) / z)(2)(1)
// -> ((3 * 2) / undefined)(1)
// -> (NaN)(1)
// -> ERROR: NaN is not a function
```

### Recursion
Now all we have to do, is make the bound function partially applicable. Easy! Recursivly call `enablePartialApplication` on it!

```js
const enablePartialApplication = (fn) => {
	return (...args) => {
		if (args.length >= fn.length) return fn(...args);
		return enablePartialApplication(fn.bind(null, ...args)); // make the bound function partially applicable
	};
};
```

With this implementation, we could chain as much as we want!

```js
const g = enablePartialApplication((a, b, c, d, e, f) => a + b - c * d / e ** f);
g(1, 2, 3, 4, 5, 6); // 2.999232
g(1, 2)(3, 4, 5)(6); // 2.999232
g(1)(2)(3)(4)(5)(6); // 2.999232
// ...
```

*AWESOME!*

### Clean up
Notice our function `enablePartialApplication` returns another function immediately. We can therefore simplify this with:

```js
const enablePartialApplication = (fn) => (...args) => {
	if (args.length >= fn.length) return fn(...args);
	return enablePartialApplication(fn.bind(null, ...args));
};
```

Like this? Share and comment! :D