{"action":"created","issue":{"url":"https://api.github.com/repos/faassen/reselect/issues/7","labels_url":"https://api.github.com/repos/faassen/reselect/issues/7/labels{/name}","comments_url":"https://api.github.com/repos/faassen/reselect/issues/7/comments","events_url":"https://api.github.com/repos/faassen/reselect/issues/7/events","html_url":"https://github.com/faassen/reselect/issues/7","id":94415940,"number":7,"title":"Add a way to shortcut evaluation","user":{"login":"HeyImAlex","id":1118591,"avatar_url":"https://avatars.githubusercontent.com/u/1118591?v=3","gravatar_id":"","url":"https://api.github.com/users/HeyImAlex","html_url":"https://github.com/HeyImAlex","followers_url":"https://api.github.com/users/HeyImAlex/followers","following_url":"https://api.github.com/users/HeyImAlex/following{/other_user}","gists_url":"https://api.github.com/users/HeyImAlex/gists{/gist_id}","starred_url":"https://api.github.com/users/HeyImAlex/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HeyImAlex/subscriptions","organizations_url":"https://api.github.com/users/HeyImAlex/orgs","repos_url":"https://api.github.com/users/HeyImAlex/repos","events_url":"https://api.github.com/users/HeyImAlex/events{/privacy}","received_events_url":"https://api.github.com/users/HeyImAlex/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/faassen/reselect/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-07-10T23:59:27Z","updated_at":"2015-07-21T21:04:26Z","closed_at":null,"body":"Just an idea for dealing with situations where a selector function should be conditional.\r\n\r\nHere's a contrived example: Imagine you have a huge list and a toggle button to do some complex filter calculations on the list. Your base selectors look like this.\r\n\r\n```javascript\r\nconst hugeList$ = state => state.hugeList;\r\nconst shouldFilter$ = state => state.shouldFilter;\r\n```\r\n\r\nOne way to handle this is by making a `filteredList$` selector that depends on `hugeList$`.\r\n \r\n```javascript\r\n// Method #1\r\n\r\nconst filteredList$ = createSelector(\r\n  [hugeList$],\r\n  (hugeList) => {\r\n    /* do expensive computation here */\r\n    return filteredList;\r\n  }\r\n);\r\n\r\nconst finalList$ = createSelector(\r\n    shouldFilter$, filteredList$, hugeList$],\r\n    (shouldFilter, filteredList, hugeList) => {\r\n        return shouldFilter ? filteredList : hugeList;\r\n    }\r\n);\r\n```\r\n\r\nThe issue is that `filteredList` is computed even if `shouldFilter` is false. If `hugeList` changed very often but `shouldFilter` was usually false, you'd be doing a lot of unnecessary re-calculation.\r\n\r\nTo avoid that you could move the `shouldFilter` check into `filteredList$`;\r\n\r\n```javascript\r\n// Method #2\r\n\r\nconst filteredList$ = createSelector(\r\n  [shouldFilter$, hugeList$],\r\n  (shouldFilter, hugeList) => {\r\n    if (!shouldFilter) { return null; }\r\n    /* do expensive computation here */\r\n    return filteredList;\r\n  }\r\n);\r\n\r\nconst finalList$ = createSelector(\r\n    [filteredList$, hugeList$],\r\n    (filteredList, hugeList) => {\r\n        return filteredList === null ? hugeList : filteredList;\r\n    }\r\n);\r\n```\r\n\r\nBut now the problem is that you recompute every time `shouldFilter` is toggled. If someone repeatedly clicks the toggle button the UI is going to start lagging hard.\r\n\r\nThe crux of the issue is that we have no way to conditionally execute a selector. We want to compute a value _under certain circumstances only_, but using memoize we can't shortcut the function without expiring our cached value.\r\n\r\nSome potential solutions:\r\n\r\n- A Symbol that can be returned to shortcut execution directly. The wrapping function would check the return value and return the cached value if it was the symbol. In the example you could just take the second method and return the special symbol instead of null.\r\n- Something like `shouldSelectorUpdate` that passes the last _used_ dependency values and the current dependency values and lets the user decide if they wanted to recompute.\r\n\r\nThe only issue I see now is the need for a default value. As this situation only comes up times that you don't actually want to use the value, it seems safe to just default to null and let the user override if they need to."},"comment":{"url":"https://api.github.com/repos/faassen/reselect/issues/comments/123476585","html_url":"https://github.com/faassen/reselect/issues/7#issuecomment-123476585","issue_url":"https://api.github.com/repos/faassen/reselect/issues/7","id":123476585,"user":{"login":"ellbee","id":6018379,"avatar_url":"https://avatars.githubusercontent.com/u/6018379?v=3","gravatar_id":"","url":"https://api.github.com/users/ellbee","html_url":"https://github.com/ellbee","followers_url":"https://api.github.com/users/ellbee/followers","following_url":"https://api.github.com/users/ellbee/following{/other_user}","gists_url":"https://api.github.com/users/ellbee/gists{/gist_id}","starred_url":"https://api.github.com/users/ellbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ellbee/subscriptions","organizations_url":"https://api.github.com/users/ellbee/orgs","repos_url":"https://api.github.com/users/ellbee/repos","events_url":"https://api.github.com/users/ellbee/events{/privacy}","received_events_url":"https://api.github.com/users/ellbee/received_events","type":"User","site_admin":false},"created_at":"2015-07-21T21:04:26Z","updated_at":"2015-07-21T21:04:26Z","body":"Another option that hasn't been suggested yet is adding a cache for the memoization like NuclearJS."}}