Introducing Bow Arch 0.1.0
Over the last year, we have worked hard to create a solid library to practice Functional Programming in Swift. Slowly, but steadily, Bow has been growing and becoming increasingly powerful. At the moment, it has three solid modules that provide most utilities you’d need to write functional code: Core, Effects, and Optics. However, we have faced the same question multiple times: How do I put everything together to build an entire application in a functional manner? Today, we are showing our proposal in the form of a new library: Bow Arch.
Bow Arch is an open source library to architect applications in a functional manner, built on solid theoretical grounds, and leveraging the power of declarative user interfaces, provided by SwiftUI.
Comonadic User Interfaces
The main pillars of the library are Comonads. When we released Bow 0.8.0, we mentioned that we had put a strong emphasis on Comonads; the reason was to leverage all that power in this library.
Comonads are algebraic structures that define a space of possible choices, from which we can select one (with the
extract operation), or perform a context-dependent operation over the entire choice space (with the
coflatMap operation). As you can probably guess, Comonads are dual structures of Monads, and, in fact, Monads also play an important role in Bow Arch. If Comonads define a space of possible choices, Monads let us navigate that space by performing actions.
One example of this is the pair
Store is a function that lets us render a value into a view; that is, the render function provides a space of all possible views that can be rendered. A
Store also contains a particular value, which is the specific value it is rendering at the moment. On the other hand,
State represents a function that produces state-based computations; that is, a function that lets us modify the state. Intuitively, given that we are rendering a view, actions that are produced within such a view should be
State values that transform the current state. We can use those actions to transform the value that is held on the
Store to move it to the following state, and render a new view as a result of this transition.
Bow Arch is heavily based on prior work done in the field of Comonadic User Interfaces, in the Haskell and PureScript communities, and, in particular, on the work done by Arthur Xavier and Phil Freeman, to whom we are very grateful. It is very exciting to see that ideas from other languages or libraries can be directly ported, even though the capabilities of Swift aren’t as great as those of Haskell and PureScript, all thanks to the usage of abstractions from Category Theory.
With its first release, Bow Arch provides specific utilities to work with Store-State based architectures, where effects are handled using IO. However, at its core, the main artifacts that power the library are highly parameterized. This allows us to use other parings of Monad-Comonad, such as Action-Moore, or to replace the effect type to use other libraries, like Combine, given that we provide the appropriate instances of type classes for the effects we’d like to use.
In this sense, Bow Arch is not only a library to architect applications, but to generate different architectures, depending on the choices we make for effects and pairings of Monad-Comonad to define our spaces and actions.
The announcement of SwiftUI at the last WWDC has also contributed to the creation of this library. SwiftUI lets us create user interfaces in a declarative manner and that can be treated as immutable values that we can work with. This enables writing views as a function of our immutable state. There are still many things to be improved in SwiftUI, but the initial result is already very promising.
Nevertheless, Bow Arch is not restricted to SwiftUI; in fact, it can be used to build command-line tools. However, we feel most Swift developers will find it useful to develop iOS, iPadOS, and macOS applications, powered by SwiftUI.
Composable and testable
The library promotes the creation of units of work in terms of components that can be used in a standalone fashion, or that can be easily composed with others. Components can be composed with others by using optics. This enables a bottom-up approach to create an application from small, individual components, that can be assembled into a bigger application that focuses on each of them using the corresponding lenses and prisms.
In addition, each artifact created in Bow Arch is based on pure functions. This makes them intrinsically testable and lets us explore complex scenarios without a complicated set up. In future versions we will continue improving the testing tools provided by the library, especially when it comes to testing SwiftUI code.
Bow Arch puts together all the previous work we have been doing on the Core, Effects and Optics modules of Bow, to have a powerful, composable way of architecting applications in a purely functional manner. The library is still in its infancy, but we are eager to show you what you can build using it. In the meantime, if you give it a try, let us know what you build!
Please check out the following Bow resources. Comments and questions are welcome and encouraged!
Bow is proudly sponsored by 47 Degrees, a Functional Programming consultancy with a focus on the Scala, Kotlin, and Swift Programming languages which supports the active development of Bow.