chapter fifteen

15 Pure functional programming

 

This chapter covers

  • Functional architecture patterns
  • Composing functions
  • Bootstrappers and inverting dependencies
  • Working with effects

So far, we’ve looked at specific language features and integration, but aside from the web application portion, much of the book so far has looked at each area in isolation. That’s been intentional so that we can focus on one thing at a time and not lose context. However, it’s also important to have an awareness of how things plug together effectively. That’s what this chapter is about: we’re going to look at different challenges you might face when writing applications that adhere to a functional programming (FP) architecture and different strategies for composing code together into larger applications.

15.1 A functional architecture pattern

While you’ve now seen how to create and work with expressions and immutable data, what probably won’t be immediately apparent is that you can (and will) create entire applications as expressions. There are even architectural patterns for this style of development, such as the onion architecture and the hexagonal (also known as the ports-and-adapters) architecture.

15.1.1 External and internal boundaries

One way you can think of your application is as being divided into two areas:

15.1.2 Structuring larger functional codebases

15.2 Composing functions

15.2.1 The object-oriented approach to composition

15.2.2 Higher-order functions

15.2.3 Dependency rejection

15.2.4 Procedural composition

15.2.5 What should you use and when?

15.3 Working with low-level dependencies

15.3.1 A worked example: Working with a logging function

15.3.2 Flipping dependencies with a bootstrapper

15.3.3 Pros and cons of the wireup pattern