Composable SwiftUI Bindings: Case Paths

Episode #108 • Jul 13, 2020 • Subscriber-Only

Now that we know that SwiftUI state management seems biased towards structs, let’s fix it. We’ll show how to write custom transformations on bindings so that we can use enums to model our domains precisely without muddying our views, and it turns out that case paths are the perfect tool for this job.

Case Paths
Introduction
00:05
Binding transformations
02:05
Bindings of optionals
14:22
Bindings of enums
25:34
Transforming with case paths
32:40
Next time: what’s the point?
45:21

Unlock This Episode

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

Introduction

However, there is clearly something not quite right about what we have done because we made quite a few strange decisions along the way. We created properties on the Status enum to project out certain information from it, but in each case that information only made sense for one of the cases. This forced us to make some choices, and it wasn’t clear that we were making the right choice. And if we ever added a third case to this enum or choices will only increase.

So what we are seeing here is that although we better modeled our core domain to properly use an enum that precisely describes the two states our item can be in, we have also accidentally destroyed all of that preciseness by trying to project out state-specific information from the general enum for our views.

And this is happening for one really important reason: quite simply, Swift favors structs over enums.

This is something we have talked about a ton on Point-Free. Swift gives first class support of many concepts and techniques for structs for which there is no corresponding story for enums. We have explained over and over again that structs and enums are really just two sides of the same coin, and any concept we introduce for one we should try searching for the corresponding concept for enums.

In this case what we are seeing is that SwiftUI simply does not give us the tools for dealing with state that is modeled as an enum. All of the tools it gives us are heavily embedded in the world of structs and product types, which leads us to trying to shoehorn tools made for structs into the world of enums.

And so without those tools we keep instinctively turning to methods of classic encapsulation to preserve invariants of our model rather than fully leveraging the benefits of structs and enums to make invalid states of unrepresentable. The idea of encapsulation is drilled into us at a very early stage as programmers as the proper way to manage complexity, but here we are seeing that even if we try to put a nice public interface over the core model we can still have complexity leak out and infect our view.

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in

References

CasePaths

Brandon Williams & Stephen Celis

CasePaths is one of our open source projects for bringing the power and ergonomics of key paths to enums.

Collection: Enums and Structs

Brandon Williams & Stephen Celis

To learn more about how enums and structs are related to each other, and to understand why we were led to define the concept of “case paths”, check out this collection of episodes:

Enums are one of Swift’s most notable, powerful features, and as Swift developers we love them and are lucky to have them! By contrasting them with their more familiar counterpart, structs, we can learn interesting things about them, unlocking ergonomics and functionality that the Swift language could learn from.

The Many Faces of Map

Brandon Williams & Stephen Celis • Monday Apr 23, 2018

To get a better understanding of the map function and how it relates to dynamic member lookup on the Binding type, catch this early episode.

Why does the map function appear in every programming language supporting “functional” concepts? And why does Swift have two map functions? We will answer these questions and show that map has many universal properties, and is in some sense unique.

Downloads