Unlock This Episode
Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.
We’ve now got a
ReducerProtocol in place along with a
ReducerBuilder, and things are looking really great. We see that we can still accomplish everything we were doing in the old style, but we are getting all new tools for simplifying and organizing our features built in the library.
But there’s still something not quite right with our
VoiceMemos reducer. It is really strange that in order to implement its
reduce method we are constructing a big, composed reducer just to turn around it hit its
reduce method to actually perform the work. The whole reason we are doing this strange dance is because we are trying to move away from defining our reducers as variables defined at the file-scope, which is an admirable goal since file-scope variables seem to put strain on the compiler. But it still feels like we haven’t quite cracked the ergonomics of this pattern yet.
It feels like there’s actually two styles of implementing reducers. First, there are the leaf node features, such as the
VoiceMemo features. In those situations we aren’t composing together and integrating multiple domains. We are just implementing the bare logic for those features in a
But then there are also the more complicated features that do need to integrate multiple domains together, and in those situations we prefer to compose things together using result builder syntax.
Amazingly, it’s possible to augment the
ReducerProtocol so that we can support both of these styles in one package. Then, at the moment of conforming a type to the
ReducerProtocol, we can decide which style do we want to implement. Are we implementing some simple standalone logic, or are we composing many things together?
Let’s see what it takes to make this happen.
The Swift evolution proposal that extended
Never to conform to
Never type, sometimes called a “bottom” type, cannot be instantiated, and can theoretically conform to most protocols.
The Swift evolution proposal that introduced primary associated types to protocols, which are what unlocked the Composable Architecture’s ability to allow reducer compositions to be more ergonomically defined.
A forum discussion about result builder generic inference and how it differs from the rest of Swift.