Functional Programming is a declarative programming paradigm where developers write software by:
- Composing pure functions,
- While avoiding mutable data and shared state,
- And pushing side-effects to the edge of the program.
Don't worry about all these terms for now, I'll explain them later in this series, with dedicated articles.
Hmmm... Ok sure, but what is a "paradigm", and what does declarative mean?
A programming paradigm is a way to classify a programming language based on some features. Basically, a programming paradigm is a way to write programs.
For single paradigm languages, since there's only 1 way of writing programs, it's easy to "stay on the track". For multi-paradigms languages, it's harder to stay on the same track, as the frontier between 2 paradigms depends solely on the developer writing the program.
One piece of the software can be written in FP, while the other can be written in OOP. Both pieces can coexist, as long as the code is adapted to jump from one way to the other. This flexibility can be both a good and a bad thing, but we won't cover this topic here.
I think it's important to say that FP is not a replacement for object-oriented programming, or any other paradigm whatsoever. It's just a different way of writing programs, which comes with some advantages we'll see in the next article.
Well that covers the paradigm part, what about the declarative part?
I won't go into many details here since I've planned on writing an article about declarative vs imperative code, later in this series.
In a nutshell, declarative programming is a style of building the structure and elements of a program by describing what the program does, and not how it does it (that's the imperative way).
A declarative program expresses the logic of a computation ("what") whereas an imperative program expresses the steps to perform a computation, explicitly ("how").
Don't worry if this is still blurry, we'll cover this part more thoroughly later.
All languages are not born equal. There is actually one requirement for writing FP code: functions must be first-class citizens of the language.
First-class what now?
A first-class citizen is an entity of the language that supports the following operations:
- Storing the entity in a variable
- Passing the entity as an argument of a function
- Returning the entity when calling a function
- Can they* be stored in variables? Yes.
- Can they be passed as arguments of other functions? Yes.
- Can they be returned when calling other functions? Yes.
* Small detail: we are not talking about the functions directly here, but rather their references.
If the language you use every day fulfills this requirement, then you can definitely implement some - if not all - of the concepts and tools we'll talk about in this series.
If that's not the case (e.g. Java < 8), then you can still learn through this series, but you probably won't be able to play with these concepts in your favorite language. And there's nothing better than some practice to actually learn new things.
Last but not least, Functional Programming comes with some "restrictions" that are better enforced with a compiler. So my recommendation would be to use a programming language that has a compiler that offers static typing.