The traditional imperative approach relies heavily upon algorithms that are supposed to produce certain phenomena at runtime—the side effects. The compiler is usually not aware of these phenomena or is not aware of them enough. We can define the side effects for this book as instructions that modify the environment outside their immediate scope. Side effects are usually not desirable, because they put extra mental load on the programmer's mind.
Another problem with the traditional imperative style is the mutation. Mutable data structures are not thread-safe. Also, they cannot be safely passed between pieces of logic even within the same thread.
Functional programming aims to resolve these problems and reduce your mental load. This style does so by abstracting away side effects, so that you write your program without explicitly performing them or mutating anything...