You should now have a better understanding of functional programming and its benefits. We've discussed the concepts of immutability and pure functions. A combination of the two often results in more testable code, which is easier to maintain.
Currying and memoization are two useful patterns that originate from functional programming.
Kotlin has a tailrec keyword that allows the compiler to optimize tail recursion. We also looked at higher-order functions, expressions versus statements, and pattern matching.
In the next chapter, we'll put this knowledge to practical use, and discover how reactive programming builds upon functional programming in order to create scalable and resilient systems.