redux: `compose` is not a normal compose

compose is a function that normally doesn’t eagerly evaluate it’s arguments, but returns a new function that, when called, does the right-to-left evaluation.

It’s easy if the composition returns a function that takes a single argument (I think this is the proper mathematical composition):

function compose(...funcs) {
  return x => {
    return funcs.reduceRight((composed, f) => f(composed), x);
  };
}

But usually we want to seed the application with multiple args, but it’s just a little more code:

function compose(...funcs) {
  return (...args) => {
    const initialValue = funcs[funcs.length - 1].apply(null, args);
    funcs = funcs.slice(0, -1);
    return funcs.reduceRight((composed, f) => f(composed),
                            initialValue);
  };
}

This changes the pattern of wrapping createStore though. One option would be to rename this to eagerCompose or something. Not sure if you all are interested in fixing this, but it is somewhat confusing that acts different than most (all?) other compose functions.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 19 (13 by maintainers)

Most upvoted comments

You can’t pass undefined. Pass a dummy function instead:

const store = createStore(reducers, {}, reduceRight(
  applyMiddleware(ReduxThunk),
  window.devToolsExtension ? window.devToolsExtension() : f => f
))

Or, if you like lodash, you can pass _.identity