Search code examples
javascriptfunctional-programmingfunction-composition

Understanding pipe function in JavaScript (functional programming)


I'm working through question 11 on bfe.dev's JavaScript coding exercises. The question asks to chain multiple basic math functions together via composition.

Here's some sample code that passes the provided test cases.

function pipe(funcs) {
    let result;
    
    return function (arg) {
        result = arg;

        for (let fn of funcs) {
            result = fn(result);
        }
        return result;
    }

}

And some driver code with the intended result, according to bfe.dev

pipe([
  times(2),
  plus(3),
  times(4)
]) 
// (x * 2 + 3) * 4

I'm struggling to understand the implementation on a code-level. pipe receives an array of functions, and I understand the approach is to walk through the array and compute the result of each function, store that in the result variable, similar to an array reduce.

But I cannot wrap my head around how the return function works, and what arg would actually be. I would appreciate a line-by-line walkthrough if possible.

Thanks in advance!


Solution

  • The example probably needs a bit more to make sense:

    const doMath = pipe([
      times(2),
      plus(3),
      times(4)
    ]) 
    
    const finalResult = doMath(5)
    console.log(finalResult);
    

    pipe's job is to create a new function. That new function has the text:

    function (arg) {
      result = arg;
    
      for (let fn of funcs) {
        result = fn(result);
      }
      return result;
    }
    

    And that is what gets assigned to doMath in my example. Then when i call doMath(5), it's going to execute the code, with arg equal to 5. It assigns 5 to result, and then starts looping through the functions (which it still has access to because this is a closure). Each function calculates a new value, which gets assigned to result, and then eventually the final result is returned. So in this case the calculation goes 5 => 10 => 13 => 52. 52 gets returned and then logged out.