Effectful State Management: Synchronous Effects

Episode #76 • Oct 14, 2019 • Subscriber-Only

Side effects are one of the biggest sources of complexity in any application. It’s time to figure out how to model effects in our architecture. We begin by adding a few new side effects, and then showing how synchronous effects can be handled by altering the signature of our reducers.

Collection
Side Effects
Effectful State Management: Synchronous Effects
Locked

Unlock This Episode

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

Sign in with GitHub

Introduction

We’re now in the final stretches of defining our application architecture. We’ve solved three of the five problems that pop up in any moderately complex application, including how the entirety of app state should be modeled in a simple value type, how this state should be mutated using simple composable functions called reducers, and how an application can be decomposed into smaller pieces that can live in their own modules and be understood in isolation.

It’s now time to solve one of the biggest problems we face when building applications: side effects. We’ve talked about side effects a bunch on Point-Free. In fact, our very second episode was dedicated to identifying side effects, understanding how they can impact function composition, and recovering composition by pushing them to the boundaries of the function. We’ve also spent several episodes on dependency injection to show that it’s completely possible to control side effects in a lightweight way using what we called the “Environment”, and how this unlocks our ability to easily simulate and test certain states in our applications that would have otherwise been very difficult.

We want to understand how to model side effects in this reducer-based architecture. There are many approaches to this problem, all with their own trade-offs, but as with everything we do on Point-Free, we want our solution to be transformable and composable.

So, we are going to identify a few flavors of side-effects in our application, and then slowly step through how we can isolate and control the effects. Let’s start by recalling what application we are building…

Adding some simple side effects


References

  • Side Effects
    Brandon Williams & Stephen Celis • Feb 5, 2018

    We first discussed side effects on the second episode of Point-Free. In that episode we showed how side effects are nothing but hidden inputs or outputs lurking in the signature of our functions. We also showed that making that implicit behavior into something explicit makes our code most understandable and testable.

    Side effects

    can’t live with ’em; can’t write a program without ’em. Let’s explore a few kinds of side effects we encounter every day, why they make code difficult to reason about and test, and how we can control them without losing composition.

  • Dependency Injection Made Easy
    Brandon Williams & Stephen Celis • May 21, 2018

    One of the easiest ways to control side effects is through the use of “dependency injection.” In an early episode of Point-Free we showed a lightweight way to manage dependencies that gets rid of a lot of the boilerplate that is common in the Swift community.

    Note

    Today we’re going to control the world! Well, dependencies to the outside world, at least. We’ll define the “dependency injection” problem and show a lightweight solution that can be implemented in your code base with little work and no third party library.

  • Redux Middleware

    Redux, at its core, is very simple and has no single, strong opinion on how to handle side effects. It does, however, provide a means of layering what it calls “middleware” over reducers, and this third-party extension point allows folks to adopt a variety of solutions to the side effect problem.

  • Redux Thunk

    Redux Thunk is the recommended middleware for basic Redux side effects logic. Side effects are captured in “thunks” (closures) to be executed by the store. Thunks may optionally utilize a callback argument that can feed actions back to the store at a later time.

  • ReSwift

    ReSwift is one of the earliest, most popular Redux-inspired libraries for Swift. Its design matches Redux, including its adoption of “middleware” as the primary means of introducing side effects into a reducer.

  • SwiftUIFlux
    Thomas Ricouard

    An early example of Redux in SwiftUI. Like ReSwift, it uses “middleware” to handle side effects.

  • Elm: A delightful language for reliable webapps

    Elm is both a pure functional language and framework for creating web applications in a declarative fashion. It was instrumental in pushing functional programming ideas into the mainstream, and demonstrating how an application could be represented by a simple pure function from state and actions to state.

  • Redux: A predictable state container for JavaScript apps.

    The idea of modeling an application’s architecture on simple reducer functions was popularized by Redux, a state management library for React, which in turn took a lot of inspiration from Elm.

  • Composable Reducers
    Brandon Williams • Oct 10, 2017

    A talk that Brandon gave at the 2017 Functional Swift conference in Berlin. The talk contains a brief account of many of the ideas covered in our series of episodes on “Composable State Management”.

Downloads

Get started with our free plan

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

View plans and pricing