{"action":"created","issue":{"url":"https://api.github.com/repos/reactjs/redux/issues/1528","repository_url":"https://api.github.com/repos/reactjs/redux","labels_url":"https://api.github.com/repos/reactjs/redux/issues/1528/labels{/name}","comments_url":"https://api.github.com/repos/reactjs/redux/issues/1528/comments","events_url":"https://api.github.com/repos/reactjs/redux/issues/1528/events","html_url":"https://github.com/reactjs/redux/issues/1528","id":141756305,"number":1528,"title":"Reducer Composition with Effects in JavaScript","user":{"login":"gaearon","id":810438,"avatar_url":"https://avatars.githubusercontent.com/u/810438?v=3","gravatar_id":"","url":"https://api.github.com/users/gaearon","html_url":"https://github.com/gaearon","followers_url":"https://api.github.com/users/gaearon/followers","following_url":"https://api.github.com/users/gaearon/following{/other_user}","gists_url":"https://api.github.com/users/gaearon/gists{/gist_id}","starred_url":"https://api.github.com/users/gaearon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gaearon/subscriptions","organizations_url":"https://api.github.com/users/gaearon/orgs","repos_url":"https://api.github.com/users/gaearon/repos","events_url":"https://api.github.com/users/gaearon/events{/privacy}","received_events_url":"https://api.github.com/users/gaearon/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/reactjs/redux/labels/discussion","name":"discussion","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":94,"created_at":"2016-03-18T02:29:12Z","updated_at":"2016-04-30T00:16:21Z","closed_at":null,"body":"Inspired by this little [tweetstorm](https://twitter.com/dan_abramov/status/710642981016100864).\r\n\r\n## Problem: Side Effects and Composition\r\n\r\nWe discussed effects in Redux for ages here but this is the first time I think I see a sensible solution. Alas, it depends on a language [feature that I personally won’t even hope to see in ES](https://esdiscuss.org/topic/one-shot-delimited-continuations-with-effect-handlers). But would that be a treat.\r\n\r\nHere’s the deal. [Redux Thunk](https://github.com/gaearon/redux-thunk) and [Redux Saga](https://github.com/yelouafi/redux-saga) are relatively easy to use and have different pros and cons but [neither of them composes well](https://github.com/reactjs/redux/issues/822#issuecomment-145271384). What I mean by that is they both need to be “at the top” in order to work.\r\n\r\nThis is the big problem with middleware. **When you [compose independent apps into a single app](https://productpains.com/post/redux/there-is-no-easy-way-to-compose-redux-applications), neither of them is “at the top”. This is where the today’s Redux paradigm breaks down—we don’t have a good way of composing side effects of independent “subapplications”.**\r\n\r\nHowever, this problem has been solved before! If we had a fractal solution like [Elm Architecture](https://github.com/evancz/elm-architecture-tutorial) for side effects, this would not be an issue. [Redux Loop](https://github.com/raisemarketplace/redux-loop) implements Elm Architecture and composes well but my opinion its API is a bit too awkward to do in JavaScript to become first-class in Redux. Mostly because it forces you to [jump through the hoops](https://github.com/raisemarketplace/redux-loop/blob/c39c533bdbfdb2581dd19806c4cd69944818d7c1/modules/combineReducers.js#L25-L26) to compose reducers instead of just calling functions. If a solution doesn’t work with vanilla `combineReducers()`, it won’t get into Redux core.\r\n\r\n## Solution: Algebraic Effects in JavaScript\r\n\r\nI think that what @sebmarkbage suggested in [this Algebraic Effects proposal](https://esdiscuss.org/topic/one-shot-delimited-continuations-with-effect-handlers) is exactly what would solve this problem for us.\r\n\r\n**If reducers could “throw” effects to the handlers up the stack (in this case, Redux store) and then continue from they left off, we would be able to implement Elm Architecture a la Redux Loop without the awkwardness.**\r\n\r\nWe’d be able to use vanilla `combineReducers()`, or really, any kind of today’s reducer composition, without worrying about “losing” effects in the middle because a parent didn’t explicitly pass them up. We also would not need to turn every reducer into a generator or something like that. We can keep the simplicity of just calling functions but get the benefits of declaratively yielding the effects for the store (or other reducers! i.e. `batch()`) to interpret.\r\n\r\nI don’t see any solution that is as elegant and simple as this.\r\n\r\nIt’s 2am where I live so I’m not going to put up any code samples today but you can read through the [proposal](https://esdiscuss.org/topic/one-shot-delimited-continuations-with-effect-handlers), combine it with [Redux Loop](https://github.com/raisemarketplace/redux-loop), and get something that I think is truly great.\r\n\r\nOf course I don’t hold my breath for that proposal to actually get into ES but.. let’s say we could *really* use this feature and Redux is one of the most popular JavaScript libraries this year so maybe it’s not such a crazy feature as one might think at first :smile: .\r\n\r\n-------------------\r\n\r\ncc people who contributed to relevant past discussions: @lukewestby @acdlite @yelouafi @threepointone @slorber @ccorcos"},"comment":{"url":"https://api.github.com/repos/reactjs/redux/issues/comments/215912975","html_url":"https://github.com/reactjs/redux/issues/1528#issuecomment-215912975","issue_url":"https://api.github.com/repos/reactjs/redux/issues/1528","id":215912975,"user":{"login":"jdubray","id":446861,"avatar_url":"https://avatars.githubusercontent.com/u/446861?v=3","gravatar_id":"","url":"https://api.github.com/users/jdubray","html_url":"https://github.com/jdubray","followers_url":"https://api.github.com/users/jdubray/followers","following_url":"https://api.github.com/users/jdubray/following{/other_user}","gists_url":"https://api.github.com/users/jdubray/gists{/gist_id}","starred_url":"https://api.github.com/users/jdubray/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdubray/subscriptions","organizations_url":"https://api.github.com/users/jdubray/orgs","repos_url":"https://api.github.com/users/jdubray/repos","events_url":"https://api.github.com/users/jdubray/events{/privacy}","received_events_url":"https://api.github.com/users/jdubray/received_events","type":"User","site_admin":false},"created_at":"2016-04-30T00:16:21Z","updated_at":"2016-04-30T00:16:21Z","body":"@ccorcos \r\n> I would say that these transient **states** are very relevant.\r\n\r\nhum...you would not consider introducing a [State](http://sam.js.org/#state) function in Redux? "}}