Chapter 1, The Declarative Programming Style, covers the main idea of declarative style of abstracting away repeating algorithmic patterns and control flows so that, with one statement, it is possible to describe what otherwise would have been 10 lines of imperative code. Functional languages usually have an elaborate infrastructure to make such an approach especially relevant and usable. One good way to feel this difference is to have a look at the difference in programming with Java and Scala collections—the former employs the imperative style and latter the functional style.
Chapter 2, Functions and Lambdas, will start with the concept familiar to an OOP programmer—a method. We will then explore some more advanced, functional concepts specific to functional programming—things such as lambdas, currying, generic type parameters, implicit arguments, and higher-order functions. We will see how higher-order functions may be useful to abstract control flow. Finally, we will look at the concept of partial functions.
Chapter 3, Functional Data Structures, explains a functional collections framework. It features a hierarchy of collections data types designed for different scenarios. It then moves to other data types that are not part of the collections framework but are often used in functional programming and hence deserve our attention. The data types are Option, Either, and Try. Finally, we will see how the data structures are separated from their behavior via an implicit mechanism, which is present in some advanced languages.
Chapter 4, The Problem of Side Effects, is about side effects that are ubiquitous in programming. Functional programming advocates for so-called pure functions—functions that do not produce any side effects, which means you can't write a file from such a function, or contact the network. Why would functional programming advocate against functions that cause side effects? Is it possible to write a useful program using pure functions only? This chapter explores these questions.
Chapter 5, Effect Types - Abstracting Away Side Effects, provides solutions to the problems of working with side effects in a pure way. The solution presented by purely functional programming is to turn the side effects you encounter into functional data structures. We will explore the process of identifying side effects and turning them into such data structures. Then, we will quickly realize functions that produce side effects usually work one with another. We will hence explore how one can combine these functions using the concept of the Monad.
Chapter 6, Effect Types in Practice, focuses on the material of the Chapter 3, Functional Data Structures, from a new perspective. We will see how functional data structures have a deeper meaning to the data types-that of representing phenomena as data. A phenomenon is something that happens, such as an exception or a delay. By representing it in data we are able to shield ourselves from the effects of the phenomenon while preserving the information about it.
Chapter 7, The Idea of the Type Classes, explore how the Type Class pattern logically emerges from practical needs encountered when working with effect types.
Chapter 8, Basic Type Classes and Their Usage, outlines the most frequently encountered type classes and their family in general. After discussing the motivation for the creation of type class systems, we proceed further to examine their structure and a few basic type classes from them. Type classes such as Monad and Applicative are frequently used in functional programming, so they deserve some special attention.
Chapter 9, Libraries for Pure Functional Programming, discusses how to use the purely functional techniques (effect types and type classes) learned so far in order to develop server-side software. We will learn how to write concurrent, asynchronous software for responding to HTTP requests, contacting the database. We will also learn about the concurrency model modern functional programming offers.
Chapter 10, Patterns of Advanced Functional Programming, explores how to combine effect types to get new effect types. You will see how to leverage the power of the compiler's type system to check guarantees about the program on compile time.
Chapter 11, Introduction to the Actor Model, starts with examining the traditional model of concurrent programming in details. This model rises a bunch of problems such as race conditions and deadlocks, which make programming in it prone to errors that are particularly hard to debug. This chapter presents the idea of an Actor model that aims to solve these problems.
Chapter 12, The Actor Model in Practice, covers the fundamentals of the framework and its concepts. You will proceed to learn some of the patterns that emerge during actor-oriented programming and also see how Actors interoperate with other widespread concurrency primitives—Futures.
Chapter 13, Use Case - A Parallel Web Crawler, examines a larger concurrent application written with the Actor model. One good such example is a web crawler application. A web crawler is an application that collects links from websites. Starting from a given website, it collects all the links on it, follows them, and recursively collects all the links from them. This chapter will examine how to implement such a larger application.
Appendix A, Introduction to Scala, is a short introduction to the Scala language, which is used for examples throughout the book.