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 RecordingMemo
and 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 reduce
method.
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.