Effectful State Management: Unidirectional Effects

Episode #77 • Oct 21, 2019 • Subscriber-Only

We’ve modeled side effects in our architecture, but it’s not quite right yet: a reducer can write to the outside world, but it can’t read data back in! This week our architecture’s dedication to unidirectional data flow will lead us there.

Unidirectional Effects
Introduction
00:05
Recap
00:11
Synchronous effects that produce results
01:45
Combining multiple effects that produce results
08:16
Pulling local effects back globally
10:15
Working with our new effects
14:48
What’s unidirectional data flow?
18:25
Next time: asynchronous effects
20:37

Unlock This Episode

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

Introduction

We have extracted our first effect into our architecture. Let’s reflect on what we just accomplished.

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

Exercises

  1. Add support for tracking the “last saved at” date on the favorite primes screen.

  2. Introduce UI that displays this “last saved at” date on the favorite primes screen.

  3. Add error handling to the load favorite primes effect. A failure to load some favorite primes is currently ignored. This means that if a user has never saved any favorite primes, an attempt to load some favorite primes will fail silently. Instead, it would be nice to present a friendly alert to the end user on failure.

    Update the favorite primes action, state, reducer, and view accordingly to support this feature.

  4. Incorporate the side effect of asking Wolfram Alpha for the “nth” prime into the counter reducer.

    In order to do so without further changing the shape of Effect, you may need to introduce some logic to make the asynchronous nature of this effect synchronous, which is something we’ve previously covered in our episode on Async Functional Refactoring.

    What kinds of problems does this solution introduce to the application?

  5. In the past on Point-Free, we have modeled asynchrony with the Parallel type, which is defined as follows:

    struct Parallel<A> {
      let run: (@escaping (A) -> Void) -> Void
    }
    

    Update Effect to have the same shape and explore how it affects the architecture and the “nth prime” effect.

References

Elm: Commands and Subscriptions

Elm is a pure functional language wherein applications are described exclusively with unidirectional data flow. It also has a story for side effects that closely matches the approach we take in these episodes. This document describes how commands (like our effect functions) allow for communication with the outside world, and how the results can be mapped into an action (what Elm calls a “message”) in order to be fed back to the reducer.

Redux: Data Flow

The Redux documentation describes and motivates its “strict unidirectional data flow.”

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 • Tuesday 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”.