How Lodash curryRight Inverts Parameter Order

Lodash’s _.curryRight transforms a function so that it accepts arguments from right to left instead of left to right. Because JavaScript typically evaluates positional and default parameters starting from the beginning of the parameter list, using _.curryRight fundamentally inverts how trailing default arguments are populated, received, and overridden.

Right-to-Left Argument Collection

In standard currying (_.curry), arguments are applied to the function's parameters in normal positional order: the first supplied argument maps to the first parameter, the second to the second, and so on.

_.curryRight reverses this flow:

function greet(greeting, punctuation, name) {
  return `${greeting}, ${name}${punctuation}`;
}

const curriedGreet = _.curryRight(greet);

// Arguments are supplied from right to left: name, then punctuation, then greeting
curriedGreet('Alice')('!')('Hello');
// Result: "Hello, Alice!"

The rightmost parameter (name) is assigned first, followed by the middle parameter (punctuation), and finally the leftmost parameter (greeting).

Inversion of Trailing Default Parameters

In standard JavaScript conventions, optional or default parameters are placed at the end of the argument list:

function sendRequest(url, method = 'GET', timeout = 1000) {
  // ...
}

Normally, a caller supplies url and allows method and timeout to fall back to their default values. When passed through _.curryRight, this sequence is completely reversed:

  1. Immediate Overriding of Defaults: The first argument supplied to the curried function binds to timeout, the second binds to method, and the final argument binds to url. Instead of keeping the defaults and providing only the required parameter, you are forced to supply values for the default parameters first.
  2. Leftover Parameters: Default values only kick in if a parameter is undefined. Because _.curryRight fills arguments into the trailing slots first, the default-valued parameters are explicitly populated upfront, meaning their default values are replaced before the required leftmost parameters are even received.

The Impact of Arity Detection (function.length)

Lodash uses a function’s .length property to determine how many arguments it needs before executing. Default parameters alter how JavaScript calculates arity:

function calculate(a, b = 2, c = 3) {}
console.log(calculate.length); // 1

In modern JavaScript, the .length property only counts parameters before the first parameter with a default value. In the function above, calculate.length is 1.

If passed into _.curryRight without an explicit arity:

const curriedCalc = _.curryRight(calculate);
console.log(curriedCalc.length); // 1

_.curryRight will consider the function satisfied after only one argument is passed. Due to the right-to-left filling, that single argument will be assigned to the first position expected from the right within the detected arity limit, executing the function immediately without waiting for b or c.

Managing Inverted Parameter Defaults

To work around this inversion when default parameters are present, an explicit arity must be passed to _.curryRight:

function configure(endpoint, retries = 3, secure = true) {
  return { endpoint, retries, secure };
}

// Explicitly define arity as 3 so all parameters are accounted for
const curriedConfig = _.curryRight(configure, 3);

// Inverted assignment: secure, retries, endpoint
const setEndpoint = curriedConfig(true)(5);
const result = setEndpoint('/api/v1');

By explicitly specifying the arity, _.curryRight reserves the correct number of slots, ensuring that arguments are intentionally assigned across all slots from right to left rather than triggering early execution.