Functional JavaScript — Partial Application and Composition
Tags: webdev, programming, javascript, flutter
Published: 2021-01-25 01:36:11

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


JavaScript is partly a functional language.

To learn JavaScript, we got to learn the functional parts of JavaScript.

In this article, we’ll look at how to use partial application and composition of functions with JavaScript.

### Partial Application

Partial application is where we only apply some of the arguments that are expected in a function.

For example, if we have a function with 3 parameters:

```
const add = (x, y, z) => x + y + z;
```

Then we can create a function that has the `add` function with arguments partially applied by writing:

```
const add1 = (y, z) => add(1, y, z);
```

Then we can use it by writing:

```
const sum = add1(2, 3);
```

And we get 6.

To generalize this, we can write:

```
const partial = function(fn, ...partialArgs) {
  let args = partialArgs;
  return function(...fullArguments) {
    return fn(...[...partialArgs, ...fullArguments]);
  };
};
```

We create our own `partial` function by returning a function with the `partialArgs` and `fullArguments` spread as arguments into the `fn` function.

Then we can use it by writing:

```
const sum = partial(add, 1)(2, 3);
```

and `sum` is 6 again.

### Currying vs. Partial Application

Currying is good whenever we need to convert functions that take multiple arguments to multiple functions that take one argument.

Situations where we need to convert a function that takes multiple arguments to a callback for `map` that only takes one parameter an example of that.

Partial application of a function is useful for any situation where we need to apply one or arguments to a function and return a function that has the arguments applied.

### Composition

Composition is where we chain multiple function calls to return the result that we want.

We have many functions that do one thing, and we combine them into one so that we can get the result we want.

For instance, we can compose the array `map` and `filter` methods by writing:

```
const arr = [1, 2, 3]
  .filter(a => a % 2 === 1)
  .map(a => a ** 2);
```

And `arr` is `[1, 9]` .

We call `filter` to return an array with only the odd numbers.

And then we call `map` to square each odd number.

### compose Function

We can generalize the compose function by writing:

```
const compose = (fn1, fn2) =>
  (c) => fn1(fn2(c))
```

Our function takes 2 functions as parameters and then we return a function that calls one after the other.

`fn2` is called first, then `fn1` is called on the result returned by `fn2` .

Then we can use it by writing:

```
let number = compose(Math.round, parseFloat)('10.1')
```

We called `compose` with `Math.round` and `parseFloat` .

`parseFloat` is called first with `'10.1'` and then `Math.round` is called on the returned result.

Then `number` is 10.

### Compose Many Functions

We can create a general version of the `compose` function by using the array `reduce` method.

For example, we can write:

```
const compose = (...fns) =>
  (value) =>
  fns.reverse().reduce((acc, fn) => fn(acc), value)
```

We created a function which takes an array of functions `fns` as a parameter.

Then we return a function that takes a value as the initial value and call `reduce` on it to call each function in the array with the returned result.

`acc` is the returned result from calling the functions so far, and `fn` is the function.

And then we can use it by writing:

```
let splitIntoSpaces = (str) => str.split(" ");
let count = (array) => array.length;
const countWords = compose(count, splitIntoSpaces)('foo bar baz');
```

We split the string by the space with `splitIntoSpaces` function.

And we get the length of the split string array with the `count` function.

And then we use `compose` to combine them together.

Once we call the returned function with a string, we get the number words separated by a space.

So `countWords` is 3.

### Conclusion

We can partially apply and compose functions with JavaScript.

Partial application lets us call functions with some arguments applied.

And composition lets us call multiple functions in a chain.