Why Use Lodash curryRight Over Standard Currying
Lodash's _.curryRight provides an inverted approach to
traditional functional currying by applying arguments in reverse order,
starting from the rightmost parameter. This article explores why
developers choose _.curryRight over standard
_.curry, focusing on how it streamlines data-last
functional programming, simplifies pipeline composition, and eliminates
the need for argument placeholders when working with standard JavaScript
APIs.
Understanding the Directional Difference
Standard currying via _.curry transforms a
multi-argument function so that arguments are supplied sequentially from
left to right. If a function is defined as fn(a, b, c),
calling _.curry(fn)(1)(2)(3) assigns a = 1,
b = 2, and c = 3.
In contrast, _.curryRight processes arguments from right
to left. Using the same fn(a, b, c), calling
_.curryRight(fn)(3)(2)(1) assigns c = 3,
b = 2, and a = 1.
Enabling "Data-Last" Functional Architecture
The primary reason to use _.curryRight is to adhere to
the "data-last" principle, a core convention of functional programming.
In functional paradigms, configuration parameters and transformation
logic should be supplied first, leaving the primary data structure (such
as an array, object, or string) as the final argument.
Standard Lodash and native JavaScript functions often follow a "data-first" signature:
// Native: target string first, search parameters last
String.prototype.includes(searchString, position);
// Standard Lodash: collection first, predicate last
_.filter(collection, predicate);When building reusable utilities, developers typically want to
configure the operation once and reuse it across multiple data sets.
_.curryRight naturally aligns standard data-first functions
with this requirement:
const filterRight = _.curryRight(_.filter);
// Supply the predicate first:
const getEvens = filterRight(n => n % 2 === 0);
// Supply the data later:
getEvens([1, 2, 3, 4]); // [2, 4]
getEvens([10, 15, 20]); // [10, 20]Eliminating Argument Placeholders
With standard _.curry, supplying a later argument while
leaving an earlier argument open requires using the Lodash placeholder
(_):
const curriedFilter = _.curry(_.filter);
const getEvens = curriedFilter(_.curry.placeholder, n => n % 2 === 0);While functional, this approach introduces visual noise and clutters
the codebase. _.curryRight accomplishes the same partial
application cleanly without placeholders because the trailing argument
(the predicate) is expected first.
Seamless Integration with Composition and Pipelines
Data processing pipelines built with tools like _.flow
or native pipe implementations rely on functions that accept a single
data input and return the modified data.
Because functions transformed with _.curryRight wait for
their primary data argument until the very end, they fit directly into
these pipeline flows:
const mapRight = _.curryRight(_.map);
const filterRight = _.curryRight(_.filter);
const processNumbers = _.flow([
filterRight(n => n > 2),
mapRight(n => n * 10)
]);
processNumbers([1, 2, 3, 4]); // [30, 40]Alternative to lodash/fp
While Lodash provides an entire functional programming variant
(lodash/fp) where all functions are auto-curried with
data-last signatures, adopting it often requires rewriting imports and
changing project conventions. _.curryRight gives developers
the flexibility to selectively achieve data-last currying on specific
operations within a standard Lodash environment without changing their
overall build configuration or library imports.