Familiarity Bias is Holding You Back: It’s Time to Embrace Arrow Functions
Eric Elliott
1.3K61

This article and the responses are fascinating on so many levels. It confirms that “People Don’t Want to Learn”. Learning requires work. We don't want to do the work.

I spent two hours deciphering the code. After I figured what it does and how it does it, it is clear to me that it is perfect. It can’t be written any better. It open my mind to few new ideas. Two hours very very well spend.

You must understand ES6, otherwise you will be trying to make sense of this:

Here is what I played with: (babeljs.io)

const pipe = (...stuff) => console.log(stuff);

Lets use it:

pipe('Hello', ' ES6 ',' rocks!');
//(3) ["Hello", " ES6 ", " rocks!"]

What if you pass functions?

pipe(x=> x + 1, x => 2*x, x => x*x);
//(3) [function, function, function]

let’s reduce:

const pipeReduced = console.log(
stuff.reduce((acc, elem) => acc + elem)
);

Lets use it:

pipeReduced('Hello', ' ES6 ',' rocks!');
//Hello ES6  rocks!

What if you pass functions?

pipeReduced(x=> x + 1, x => 2*x, x => x*x);
// function (x) {
// return x + 1;
// }function (x) {
// return 2 * x;
// }function (x) {
// return x * x;
// }

But we want to execute the functions not print them:

const pipe = (...funcs) => funcs.reduce((acc, fun) =>fun(acc),0);

Here you pass a list of functions to pipe. …funcs creates an array of the functions. funcs.reduce calls each function starting with the argument 0 then adds the result to the accumulator acc.

Let’s use it:

console.log(pipe(x=> x + 1, x => 2*x, x => x*x));
// 4 

The result 4 is from 0+1 -> 2*(0+1) -> (2*(0+1))*(2*(0+1))

Let’s replace the 0 with input argument.

Now we curry :)

const noCurry = (x,y) => x + y;
console.log(noCurry(2,3));
//5
const withCurry = x => y => x + y;
console.log(withCurry(2)(3));
//5
//OR
const addTwoTo = withCurry(2);
console.log(addTwoTo(3));
//5

Back to our pipe:

const pipe = (...funcs) => funcs.reduce((acc, fun) =>fun(acc),0);
//becomes
const pipe = (...funcs) => x => funcs.reduce((acc, fun) =>fun(acc),x);

Use it:

const myPipedFun = pipe(x=> x + 1, x => 2*x, x => x*x);
console.log(myPipedFun(0))
//4
//The result 4 is from 0+1 -> 2*(0+1) -> (2*(0+1))*(2*(0+1))
// function pipe will apply a series of functions 
// one after another to an argument.
// (g(),f(),t())(x) -> t(f(g(x)))
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
// function compose will apply a series of functions 
// one after another =but= from right to left to an argument.
// (g(),f(),t())(x) -> g(f(t(x)))
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
//few functions
const square = x => x*x;
const addOne = x => x + 1;
const double = x => 2*x;
const double_addOne_square = compose(square, addOne, double);
const square_addOne_double = pipe(square, addOne, double);
console.log(double_addOne_square(3))
//49 from 2*3 then (2*3) + 1 then ((2*3) + 1)*((2*3) + 1)
console.log(square_addOne_double(3))
//20 from 3*3 then (3*3) + 1 then 2*((3*3) + 1)

That worked. But what is the purpose of the more complicated function in the article:

const composeMixins = (...mixins) => (
instance = {},
mix = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x)
) => mix(...mixins)(instance);

So… the

(...fns) => x => fns.reduce((acc, fn) => fn(acc), x)

is the pipe function from my experiments.

Then this is the same:

const composeMixins = (...mixins) => (
instance = {},
mix = pipe
) => mix(...mixins)(instance);

Or we can use compose

const composeMixins = (...mixins) => (
instance = {},
mix = compose
) => mix(...mixins)(instance);