Unlock This Episode
Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.
Introduction
The ease at which we modularized these reducers speaks to just how modular this architecture is by default. We didn’t have to make any striking refactors or changes to logic because the boundaries are already very clearly defined. The worst things got was the need to introduce a little extra boilerplate for a component that had more complex state.
Subscribe to Point-Free
Access this episode, plus all past and future episodes when you become a subscriber.
Already a subscriber? Log in
Exercises
Another way to isolate code is to move it to its own file and mark part of it
private
orfileprivate
. How does this kind of modularization differ from using an actual Swift module?In this episode we discussed how it was not appropriate to give the name
map
to the transformation we defined onStore
due to the trickiness of reference types. Let’s explore definingmap
on another type with reference semantics.Previously on Point-Free, we defined a
Lazy
type as a struct around a function that returns a value:struct Lazy<A> { let run: () -> A }
Upgrade this struct to a class so that we can introduce memoization. A call to
run
should perform the given closure and cache the return value so that any repeat calls torun
can immediately return this cached value. It should behave as follows:import Foundation let slow = Lazy<Int> { sleep(1) return 1 } slow.run() // Returns `1` after a second slow.run() // Returns `1` immediately
From here, define
map
onLazy
:extension Lazy { func map<B>(_ f: @escaping (A) -> B) -> Lazy<B> { fatalError("Unimplemented") } }
Given our discussion around
map
on theStore
type, is it appropriate to call this functionmap
?Sometimes it can be useful to
view
into a store so that it removes all access to the underlying state of the store. For example, a “debug” screen for your app could have a UI for listing out every single action in your application as buttons, and tapping the button will send the action to the store. Such a screen doesn’t need any access to the app state.Try building such a screen, and provide it
view
of the store that removes all access to the underlying app state.Write a function that transforms a
Store<GlobalValue, GlobalAction>
into aStore<GlobalValue, LocalAction>
. That is, a function of the following signature:extension Store { func view<LocalAction>( /* what arguments are needed? */ ) -> Store<Value, LocalAction> { fatalError("Unimplemented") } }
What kind of data does the function need to be supplied with in addition to a store? Is this kind of transformation familiar? Does it have a name we’ve used before on Point-Free?
References
The Many Faces of Map
Brandon Williams & Stephen Celis • Monday Apr 23, 2018Why does the
map
function appear in every programming language supporting “functional” concepts? And why does Swift have twomap
functions? We will answer these questions and show thatmap
has many universal properties, and is in some sense unique.
Contravariance
Brandon Williams & Stephen Celis • Monday Apr 30, 2018We first explored the concept of “positive” and “negative” position of function arguments in our contravariance episode. In this episode we describe a very simple process to determine when it is possible to define a map
or pullback
transformation on any function signature.
Let’s explore a type of composition that defies our intuitions. It appears to go in the opposite direction than we are used to. We’ll show that this composition is completely natural, hiding right in plain sight, and in fact related to the Liskov Substitution Principle.
Why Functional Programming Matters
John Hughes • Saturday Apr 1, 1989A classic paper exploring what makes functional programming special. It focuses on two positive aspects that set it apart from the rest: laziness and modularity.
Access Control
AppleThis chapter of the Swift Programming Language book explains access control in depth and how it affects module imports.
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, 2017A 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”.