Neat Trick for JavaScript Developers to Know: Exploring  A Different Way to Function Chain

Neat Trick for JavaScript Developers to Know: Exploring A Different Way to Function Chain

This is not a dot-chaining function.

It's just a neat thing I found while doing easier algos for fun, but the problem is not really relevant to this article; I am only using it as an example to help conceptualize a use case for why you might chain a function.

In this problem:

/**

 * Loop through the queue, invoking the functions in order with the input number,

 * where the results of each invocation become the next function’s input.

 * Additionally, the queue should be empty after the function is called.

 * let puzzlers = [

 *   function(a) { return 8  a - 10; },

 *   function(a) { return (a - 3)  (a - 3) * (a - 3); },

 *   function(a) { return a  a + 4; },

 *   function(a) { return a % 5; }

  ];

 * let start = 2;

 * applyAndEmpty(2, puzzlers); // → 3

 */        

You can solve it like:

function applyAndEmpty(input, queue) {

  while (0 < queue.length) {

    const func = queue.shift(); //removes function definition and stores it in func 

    input = func(input);

  }

  return input;

}        

or you can remove the function and call it in one line like:

function applyAndEmpty(input, queue) {

  while (0 < queue.length) {

    input = queue.shift()(input); // removes the function and invokes it immediately

  }

  return input;

}        

simple explanation:

This works because in the expression queue.shift()(input), queue.shift() is going to remove the first function from the queue, but the evaluated result of queue.shift() is the function that was removed. Typically, we would store this value somewhere, but in this case, instead of storing it in a new label, we realize queue.shift(), in essence, will be the function, so we invoke it immediately. You probably more commonly see this used like:

const arr = [0, 1, 2, 3];

let element = arr.slice(2)[0]; //arr.slice(2) returns an array -> [2, 3] and we just then we set "element" equal to the zeroth element of the array 

console.log(element); // -> 2        

extension unnecessarily in depth if you go to: http://www.javascriptkit.com/jsref/precedence_operators.shtml, you can see the "Precedence" each Operator has, and their "Associativity" "." (dot property reference), and "()", the empty parenthesis can be any number of things, in this case, the parenthesis indicates that a function is being called, have the same precedence next we look at the associativity and it reads left to right.

I can break down Precedences, Associativity, and left-to-right V.S. right-to-left in a different article if anyone wants.


But, at the deepest level, I can explain everything going on in the order it goes on:

queue: Represents an array of functions.

queue.shift: Represents the arrays slice method.

queue.shift(): Invokes the shift method on queue, returning the first element of the array the method was called on, in this case, a function.

queue.shift()(input): Invokes the function returned by queue.shift(), passing input as an argument, and returns the evaluated result.


The final part I promise:

For you fellow math nerds, if x = 2, x is two, they are interchangeable. 3 + 2 = 5, but 3 + x also equals 5. So when we have the array from the problem:

let queue = [

    function(a) { return 8  a - 10; },

    function(a) { return (a - 3)  (a - 3) * (a - 3); },

    function(a) { return a  a + 4; },

    function(a) { return a % 5; }

  ];        

queue.shift() = function(a) { return 8 * a - 10; }

They are interchangeable. Now, obviously, you can't invoke a function like:

function(a) { return 8 * a - 10; }(10); - Except you actually can, give it a try

In:

const what = function(a) { return 8 * a - 10; }(10);
console.log(what); // I already spoiled it but what do you think this returns? Or does it return anything?        

We just took a deep dive into one way to function chain.

Maybe you already knew about function chaining like this, in which case I hope I talked about something you knew worked but never really thought about why or helped you so that instead of just intuitively knowing it works and why, a way for you to conceptualize it so that you can now tell others why in an easily digestible way.

David Moore insightful as ever. Your exploration into associativity and precedence is something a lot of devs never get exposure to--thanks for sharing!

To view or add a comment, sign in

More articles by David Moore

Others also viewed

Explore content categories