Reducer Protocol: Composition, Part 2

Episode #204 • Sep 12, 2022 • Subscriber-Only

The new reducer protocol has improved many things, but we’re now in an awkward place when it comes to defining them: some are conformances and some are not. We’ll fix that with inspiration from SwiftUI and the help of a new protocol feature.

Previous episode
Reducer Protocol: Composition, Part 2
Next episode

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Sign in with GitHub


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.

Inspiration from SwiftUI



Get started with our free plan

Our free plan includes 1 subscriber-only episode of your choice, access to 62 free episodes with transcripts and code samples, and weekly updates from our newsletter.

View plans and pricing