Unlock This Episode
Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.
Introduction
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.
Subscribe to Point-Free
Access this episode, plus all past and future episodes when you become a subscriber.
Already a subscriber? Log in
References
SE-0215: Conform Never to Equatable and Hashable
Matt Diephouse • Thursday May 24, 2018The Swift evolution proposal that extended Never
to conform to Equatable
and Hashable
. The Never
type, sometimes called a “bottom” type, cannot be instantiated, and can theoretically conform to most protocols.
SE-0346: Lightweight same-type requirements for primary associated types
Pavel Yaskevich, Holly Borla, Slava Pestov • Friday Mar 11, 2022The 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.
Function builder cannot infer generic parameters even though direct call to `buildBlock` can
Dan Zheng, Holly Borla, Doug Gregor, et al. • Sunday Apr 26, 2020A forum discussion about result builder generic inference and how it differs from the rest of Swift.