The definition of functional programming is quite easy. Functional programming is the programming with mathematical functions. Is that all? Of course, not!
Functional programming is the programming with mathematical functions. I think, you already guess it. The key to this definition is the expression mathematical function. Mathematical functions are functions that return every time the same result when given the same arguments. They behave like an infinite big lookup table.
The property, that a function (expression) always returns the same result when given the same arguments, is called referential transparency. Referential transparency has far reaching consequences:
- Mathematical functions can not have a side effect and can therefore not change the state outside the function body.
- The function call can be replaced with its result, but can also be reordered or put on a different thread.
- The program flow is defined by the data dependencies and not by the sequence of instructions.
- Mathematical functions are a lot easier to refactor and to test because you can reason about the function in isolation.
That sounds very promising. But which so many advantages, there is a massive restriction. Mathematical functions can not talk to the outside world. Examples?
Mathematical functions can't
- get user input or read from files.
- write to the console of into a file.
- return random numbers or time, because the return values are different.
- build a state.
Thanks to mathematical functions, the definition of functional is very concise but helps not so much. The key question still remains. How can you program something useful with functional programming? Mathematical functions are like islands that have no communication with the outside world. Or to say it in the words of Simon Peyton Jones, one of the fathers of Haskell. The only effect that mathematical functions can have is to warm up your room.
Now I will be a little bit more elaborated. What are the characteristics of functional programming languages?
Characteristics of functional programming languages
Haskell will help me a lot on my tour through the characteristics of functional programming.
There are two reasons for using Haskell.
- Haskell is a pure functional programming language and therefore you can study very well the characteristics of functional programming by using Haskell.
- Haskell may be the most influential programming language of the last 10 - 15 years.
My second statement needs a proof. I will provide them in the next post for Python and in particular C++. Therefore, a few words about Java, Scala, and C#.
- Philip Wadler, another father of Haskell, was one of the implementors of generics in Java.
- Martin Odersky, the father of Scala, that adapted a lot from Haskell, was also involved in the implementation of generics in Java.
- Erik Meijer is a passionate admirer and researcher around Haskell. He used the Haskell concepts of monads and created the well know C# library LINQ.
I will even go one step further. How knows functional programming and in particular Haskell, know, how the mainstream programming languages will develop in the next years. Even a pure object-oriented language like Java can not withstand the pressure of the functional ideas. Java has now generics and lambda expressions.
But now back to my subject. What are the characteristics of functional programming languages?
On my search for the functional characteristics, I identified seven typical properties. These must not be all characteristics and each functional programming language has not to support them. But the characteristics helps a lot to bring meat to the abstract definition of functional programming.
The graphic gives, on one hand, the characteristics of functional programming and gives, on the other hand, the outline of my next posts. I will provide a lot of examples in Haskell, C++, and Python. But what do the seven characteristics mean?
First-class Functions are typical for functional programming languages. These functions can accept functions as an argument or return functions. Therefore, the functions have to be higher-order functions. That means, they behave like data. Pure functions always return the same result when given the same arguments and can not have a side effect. They are the reason that Haskell is called a pure functional language. A pure functional language has only immutable data. That means, they can not have a while or for loop which is based on a counter. Instead of the loops, they use recursion. The key characteristic of functional programming is that you can easy compose functions. This is because of their bread and butter data structure list. If an expression evaluates its arguments immediately, it's called greedy or eager evaluation. If the expression evaluates the arguments only, if needed, it's called lazy evaluation. Lazy evaluation will reduce time and memory if the evaluated expression is not needed. I think, you already guess it. The classical programming languages are greedy. They evaluate their expressions immediately.
I start in my next post with first-class functions. We have them since the beginning of C++.
Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library". Get your e-book. Support my blog.