Using Lodash flow to Compose Functions Left to Right

This article explains how the _.flow method in the Lodash JavaScript library creates a function pipeline through left-to-right composition. You will learn the mechanics behind how arguments are passed between composed functions, see practical code demonstrations, and understand how to implement the underlying logic using native JavaScript.

Understanding _.flow

In functional programming, function composition is the process of combining two or more functions to produce a new function. While mathematical composition traditionally evaluates from right to left, Lodash provides _.flow to evaluate functions in natural reading order: from left to right.

The _.flow method takes an array of functions (or functions supplied as individual arguments) and returns a new composite function.

const _ = require('lodash');

const add = (x, y) => x + y;
const square = n => n * n;
const double = n => n * 2;

const transform = _.flow([add, square, double]);

transform(2, 3); // Output: 50

How Evaluation Works Step-by-Step

When the composed function produced by _.flow is invoked, the execution follows a strict sequence:

  1. Initial Invocation: The first function in the pipeline can accept multiple arguments. In the example above, add(2, 3) receives both inputs and evaluates to 5.
  2. Intermediate Handoff: The return value of the first function is supplied as the sole argument to the second function. Here, square(5) evaluates to 25.
  3. Pipeline Continuation: Each subsequent function receives the resolved output of the function directly preceding it. double(25) evaluates to 50.
  4. Final Output: The return value of the final function in the sequence becomes the return value of the entire composite function call.

Native JavaScript Equivalent

Under the hood, _.flow operates essentially like Array.prototype.reduce. Understanding this implementation demystifies the behavior:

const customFlow = (...funcs) => {
  return (...initialArgs) => {
    return funcs.slice(1).reduce((accumulator, currentFunc) => {
      return currentFunc(accumulator);
    }, funcs[0](...initialArgs));
  };
};

const processNumber = customFlow(
  (a, b) => a + b,
  n => n * 3,
  n => `Result: ${n}`
);

console.log(processNumber(4, 2)); // Output: "Result: 18"

In this mechanism, the accumulator holds the intermediate result at each step, moving forward through the list of functions until the final result is calculated.

Practical Use Case: Data Transformation

Left-to-right composition is particularly useful for readable data sanitization and transformation pipelines:

const trim = str => str.trim();
const toLowerCase = str => str.toLowerCase();
const removePunctuation = str => str.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "");
const splitWords = str => str.split(" ");

const cleanAndTokenize = _.flow([
  trim,
  toLowerCase,
  removePunctuation,
  splitWords
]);

const tokens = cleanAndTokenize("  Hello, World! Welcome to Lodash.  ");
// Result: ["hello", "world", "welcome", "to", "lodash"]

Without _.flow, performing these operations requires either nested function calls evaluated from the inside out (splitWords(removePunctuation(toLowerCase(trim(text))))) or storing intermediate values in temporary variables.

_.flow vs. _.flowRight

Lodash also provides _.flowRight, which is an alias for traditional mathematical composition (compose). The distinction is purely directional:

For readability and consistency with standard data processing pipelines, _.flow is preferred because its execution matches standard top-to-bottom or left-to-right reading order.