Sign in
Log inSign up
High Order Functions with Reduce — Compose from Recompose

High Order Functions with Reduce — Compose from Recompose

Thiago Marinho's photo
Thiago Marinho
·Oct 9, 2018

Introduction

Hello, what's up? I want to talk about an advanced concept of Javascript.

Motivation

Everybody knows that Javascript is very hard when we begin to advance on in its studies. In order to know this post and how you can use it, your skills must be advanced in JS! Someone told me that so I can say it as well.

Let's understand this algorithm.

const compose = (...funcs) =>
  funcs.reduce((a, b) => (...args) => a(b(...args)))

Minimum requirements

  • The wisdom of the basic Javascript (let, const, var, array, function)
  • Knowledge in ES06, destructuring parameters, array functions, HOC, "this is it, no big deal".
  • Be curious, willing to learn, to ask and to give feedback.

Use Case

The function Compose is very useful in React applications that use the Recompose lib for handling with Smart/Dumb components and to write fewer lines of code. Take a look in the line above, I've called the function Compose that returns to the BirthdaysContainer the pure component Birthdays, it is just a view (screen) of birthdays with all dates loaded, data and withApollo. The BirthdaysContainer is most used in Router, and Router is rendered inside of App.js. Ok, let's go back to the main subject, I just wanna share an advantage to use recompose/compose.

1_eCVJvPsKZoWRszqAfCZpEw.png

Explanation

Read the code more one time. It is very boring to debug the reduce method, so I leave everything easy to you, a cinch, and to show piece-by-piece of the code. Whatever question, suggestion or something wrong, just let me know in the comments section below.

const compose = (...funcs) =>
  funcs.reduce((a, b) => (...args) => a(b(...args)))

I've created five functions very easily that make "sum" for us. All of them receive a number as a parameter and make the sum with the value specified in the function.

const add1 = (num) => num + 1;
const add2 = (num) => num + 2;
const add3 = (num) => num + 3;
const add4 = (num) => num + 4;
const add5 = (num) => num + 5;

const compose = (...funcs) =>
        funcs.reduce((a, b) => (...args) => a(b(...args)))

console.log(compose(add1,add2,add3,add4,add5)(5));

The function add1 receives a number and make sum by 1, function add2 receives any number that sums by 2, and so on.

Compose

Take a look at line 10, the console.log() that is used to display the results of have called function Compose.

When the Compose method is called, I pass five functions to it as a parameter, and as the return of compose is a function, then I pass another parameter (5) for the return of the function.

1_9diJxJabvT8NmWN73zWB-Q.png

If you to call the function and add a parameter to it that was returned, it runs the function returned with the parameter it got. In this case above, I give 5 and I got the sum from 5 + 1 = 6.

const compose = (...funcs) =>
  funcs.reduce((a, b) => (...args) => a(b(...args)))

The arguments that were received from Compose it is going to be destructured and created an array with all parameters.

const compose = (...funcs) =>
        funcs.reduce((a, b) => (...args) => a(b(...args));

compose(add1, add2, add3, add4, add5)(5);

const compose = (...funcs) =>
        [add1,add2,add3,add4,add5].reduce((a, b) => (...args) => a(b(...args));

That's why I can use the reduce method on parameter funcs, because funcs is an array from received parameters.

(…args) => a(b(…args)

// iteração
1: add1(add2(5))
2: add1(add2(add3(5)))
3: add1(add2(add3(5)))
4: add1(add2(add3(add4(5)))
5: add1(add2(add3(add4(add5(5)))))

The function is just solved, but no called yet, the calling of functions happens after each iteration and the Reduce return the function and runs it.

After the end of the fifth iteration above, the reducer returns the result of the execution of the function, that comes to reducing (solving).

1: add1(add2(add3(add4(add5(5)))))
2: add1(add2(add3(add4(10)))
3: add1(add2(add3(14)))
4: add1(add2(17))
5: add1(19)
6: // 20

We see clearly the return and calling of the function. The function that calls a function, what in turn, this function returns another function, namely, High Order Function (HOF).

5 + 5 = 10 + 4 = 14 +3 = 17 + 2 = 19 + 1 = 20

That is all folks! (All of that showed for just this piece of code!) LOL.

The great complexity is just getting the flux of reduce method in an array of functions, and that returns a function. That's like magic and too hard to debug.

So far everything is clear when you use some famous library and until design your systems. This function uses mightly the concept of functional programming. It allows you to do the things more declarative instead of imperative.

It's too complicated and it takes some time to get it. However, you will get the hang of it later on. I've written it just because I understand quite well this concept and I would like to share it.

Additionally, I look forward to getting some feedback.

Thank you for reading!