There are many ways to examine problems and model their solutions. In software, we tend to look at problems through the lens of our experiences and the tools that we have at our disposal. In other words, our experiences and the tools we know influence how we approach solving problems. For example, in the days of structured programming, we solved many problems using procedural decomposition and subroutines, focusing on internal cohesion and loose coupling. Building on these successful techniques, we transitioned to modeling solutions using objects and object-oriented techniques, further encapsulating imperative code and its data.
While object-oriented design and object-oriented programming will continue to play a significant role in years to come, I believe we are facing challenges that require new ways of thinking and new ways of implementing solutions. For example, massive computing power via multi-core architectures and cloud computing will make developing
concurrent systems and parallel algorithms a virtual necessity. Functional programming provides us with many of the tools and technique we need to make this a reality. Additionally, functional programming gives us new ways of developing scalable systems that are easy to debug and test.
What is Functional Programming?
Functional programming is a specific way to look at problems and model their solutions. Pragmatically, functional programming is a coding style that exhibits the following characteristics:
· power and flexibility – we can solve many general real-world problems using functional constructs
· simplicity – most functional programs exhibit a small set of keywords and concise syntax for expressing concepts
· suitable for parallel processing – via immutable values and operators, functional programs lend themselves to asynchronous and parallel processing
Functional programming treats computation, e. g., running a program or solving a numeric calculation, as the evaluation of functions. Not surprisingly, in dealing with functional programming, we will use the term function quite often and in many contexts. So, before we continue, let’s make sure we understand what a function is:
A function is fundamentally a transformation. It transforms one or more inputs into exactly one output.
An important property of pure functions is that they yield no side effects. This means that the same inputs will always yield the same outputs, and that the inputs are not changed as a result of the function. This idea of “no side effects” is one (of several) that makes functional programming particularly attractive when writing multi-process and multithreaded systems. As we go through the book, I will point out and explain the key concepts that make functional programming attractive for solving certain types of problems.
Some programming languages are “purely functional languages.” This means that they follow strict functional rules, e. g., no imperative looping constructs and no implicit way to introduce state changes. For example, Haskell, a pure functional language, disallows state changes and side effects altogether. Programs written in pure functional languages are almost solely made up of functions that accept arguments and return values. Unlike imperative and object-oriented languages, they allow no side effects and use recursion instead of loops for iteration.