Before You Begin
This section tells you a few things you need to know before you get started, such as what you’ll need for hardware and software, where to find the project files for this book, and more.
Section I: Functional Programming Fundamentals
This is the very start of your functional programming journey. Here, you’ll learn what functional programming is and why it’s useful as well as its fundamental concepts. Using hands-on examples every step of the way, you’ll discover pure functions, higher-order functions, composition and so much more!
Functional programming is a programming paradigm where programs are constructed by applying and composing functions. In this chapter, you’ll learn why functional programming is important and how it can make your code more robust, readable and testable.
In this chapter, you’ll start thinking functional. You’ll be introduced to category theory, and you’ll learn how the category of types and functions relates to functional programming. From the concepts of initial and terminal object of a category, you’ll understand where some of the Kotlin fundamental types come from — all this while having fun with logic and exercises.
Not all functions are the same. In this chapter, you’ll learn what pure functions are and why they’re important. You’ll understand the concepts of referential transparency and, using the substitution model, you’ll learn how to validate the purity of a function. In the last part of the chapter, you’ll start learning the basics of another fundamental concept: side effects.
Lazy evaluation and memoization are two of the most important advantages you get when writing pure functions. In this chapter, you’ll learn what an evaluation strategy is and how to achieve lazy evaluation using lambda expressions.
Functional programming allows you to have a declarative approach in the creation of reusable and more readable code. This is possible through the use of higher-order functions, the topic of this chapter.
Immutability and recursion are concepts you need to understand for implementing functional data structures. In this chapter, you’ll learn why immutability is something you should pursue and what the challenges are when using immutable code.
Functional data structures and, in particular, persistent data structures are fundamental tools for implementing functional programming code. In this chapter, you’ll learn what they are, and you’ll implement the main function of a singly linked list.
Composition is the most important concept of functional programming but not the easiest to understand and implement. In this chapter, you’ll learn how to compose pure functions as well as functions with side effects.
Section II: Data Types & Typeclasses
In this section, you’ll learn some of the types you see when using functional programming. You’ll see concepts you likely already know, like “List” and “Optional”, while discovering some of their very important properties as they relate to functional programming.
Data types are fundamental tools in the implementation of programs using the functional programming approach. In this chapter, you’ll learn all about data types, their analogies with the concept of containers and how you can interact with their content in a safe and pure way.
Functional programming has a strong relationship with math. In this chapter, you’ll learn what algebra is and how to apply some basic math principles to important functional programming concepts like currying.
Functors map objects and morphisms in one category to objects and morphisms in another while preserving their structures. But what does this really mean, and what are the practical consequences? This chapter will answer this and other questions about functors.
Monoids and semigroups are two very simple but powerful typeclasses you frequently find and use in your code. In this chapter, you’ll learn all about them and see how to prove their laws using property-based testing.
Monads are one of the most challenging but rewarding concepts in functional programming. They’re how you compose functions handling side effects. In this chapter, you’ll understand what they are, and more importantly, how to use them.
Section III: Functional Programming in Practice
Time to put all that knowledge to work. In this section, you’ll use all the principles you’ve learned so far to see the functional programming way for handling errors and managing state changes. You’ll also meet some libraries you can use in your projects to quickly introduce functional programming.
Handling errors and exceptions is what makes your software reliable. In this chapter, you’ll see how to handle exceptions using all the functional programming concepts you learned in the first two sections of the book.
In this chapter, you’ll learn all about the state data type as a way to control the side effects of an impure function.
Controlling side effects is one of the most important topics in functional programming. In this chapter, you’ll learn how to handle them using the IO monad.
Lists, sequences and flows are probably tools you use every day in your job. In this chapter, you’ll learn what functional programming principles they follow and how to make them even more powerful.
In this chapter, you’ll see how the functional programming principles you learned in the previous chapters are used in the creation of Mobius, an interesting implementation of a unidirectional flow architecture.
Arrow is one of the most important libraries that allows you to apply functional programming concepts to your Kotlin code. In this chapter, you’ll get a first taste of Arrow and how it can help you write pure code in your project.
This book has many exercises and challenges throughout. In this appendix, you’ll find solutions to all exercises and challenges, along with additional explanations about the answers.