You probably have heard expressions like “Clojure”, “Scala”, “Erlang” or even “Java now has lambdas”. And you might know it has something to do with "Functional Programming". If you’re participating to any Programming Community, this subject probably has popped up already.
If you'd google "Functional Programming", you'll see there's nothing new. One of the first language created already embraces it, it appeared in 50's and was named Lisp. So why the heck people are only excited about it now? Around 60 years later?
At the beginning, Computers were really slow
Believe it or not, Computers were waaay slower than the DOM. No, really. And at that time, there was 2 main mindsets in terms of design and implementation of programming languages:
- Start from the Von Neumann Architecture and add abstraction.
- Start from Mathematics and remove abstraction.
The computers didn't have that much processing power to deal with abstractions from all the way down to evaluate functional programs. So, Lisp ended up being deadly slow and, therefore, not suited for the job. That's when imperative programming started its domination, specially with the rise of C.
But Computers have improved a lot
Now it's virtually OK to run the most of applications out there without caring so much about which language it has been written in. Finally, functional languages got their second chance.
Functional Programming 50.5
This isn't an introduction to FP at all. At the end of this section, you should be able to have an idea of what FP might be and how to start your journey.
You can understand Functional Programming as programming with functions, which is, in fact, much more literal than you can imagine now. You'll create functions in terms of other functions and compose functions (Do you remember the f ∘ g from school? It'll be useful now). That's all.
Here's a (non-exhaustive) list of FP features:
- First-Class Functions
- High-Order Functions
- Pure Functions
- Immutable State
You shouldn't care about fancy names right now: Just understand what they mean.
You're just storing an anonymous function, that receives a and b and returns a + b, into a variable named add.
High-Order Functions mean that functions can return functions or receive other functions as params.
Both of cases are an example of High-Order Functions, even though you've never coded anything like that, you probably have seen this pattern somewhere else.
Pure Functions mean that the function doesn't change any value, it just receives data and output data, just like our beloved functions from Mathematics. That also means that if you'd pass 2 for a function f and it returns 10, it'll always return 10. Doesn't it matter the environment, threads, or any evaluation order. They don't cause any side-effects in other parts of the program and it's a really powerful concept.
Closures mean that you can save some data inside a function that's only accessible to a specific returning function, i.e the returning function keeps its execution environment.
Check out the second example of High-Order Function again, the variable a was enclosed and is only accessible to the returning function. In fact, Closures aren't a proper FP feature, but an optimization.
Immutable State means that you can't change any state at all (even though you can get a new state). In this following code (in OCaml), you can use x and 5 interchangeably in your program. x will be forever 5.
Object-oriented Programming cannot save us anymore
That promised time when we'd have applications running distributed and concurrently finally has come. Unfortunately, we are not ready: our "current" (i.e., most used) model for concurrency and parallelism, even though might solve the problem, it adds a lot of complexity.
For a better applications, we need a simple and reliable manner to do it. Do you remember above-mentioned features of FP? Pure Functions and Immutable State? Exactly. You can run a function a thousand of times in different cores or machines that you're not going to get different outputs from what you've gotten before. So, you can use the same code to run in 1 core as well as 1k. Life can be good again.
"But why can't I keep using OOP?"
At least for concurrency and parallelism, OOP cannot save you anymore. It's just because OOP relies directly on mutable state (in Imperative Languages, which are the most common OOP implementation). The Object's methods you call is supposed to mutate the current self or this. A lot of complexity will be needed to keep all threads correctly updated and synchronized.
I'm not here to argue that you must move from your whatever paradigm to FP (even though some people would say you must), but you definitely need to master it: Java and C++11 already got lambda expressions. I can say that almost every modern and maintained language is going to rely on FP features soon. And most of them already do.
It's worth mentioning you are not going to stop using mutable state. We need to use IO, etc to have a useful program. The main idea FP provides is: use mutable state only when it's necessary.
"I'm not working on Clouds, do I really need FP?"
Functional Programming will help you write better programs and reason about the problems you have to solve.
"I've tried. It's too complex and it has poor readability"
Every thing is hard at first. I'm sure you've struggled to learn how to program and even to learn OOP. Probably start doing something in OOP was way easier than your first program. Mainly because you're already familiar with some common idioms, like variable declaration and for/while loops.
For starting with FP, it's almost like starting to learn how to program again, from scratch (depending on which language you'd start, it'll be definitely like starting over again).
Many may argue that FP has poor readability. If you'd have a imperative background, functional programs will look like a crypt language. Not because it's actually crypt, but because you still don't know its common idioms. Once you master its fundamentals, it gets a lot more readable.
It's a very simple program. It outputs a congrats message when the user correctly inputs 7 or outputs an error message otherwise. It might look crypt how Haskell can do it in only 2 lines of code (just ignore the first line for now, it's just "type annotation"). But it's actually very simple once you understand the Pattern Matching feature (which is not only implemented in FP languages, but specially in those ones).
What Haskell is doing:
If the argument the guess function receives is equal to 7, it'd return “Much 7 very wow.” or return “Ooops, try again.” otherwise.
It may seem it isn't worth using once you can simply use if/else instead. But it gets really powerful when working with complex data structures.
In the program above, plus1 is a function that receives a List of Ints and adds 1 to each element of it. It matches over an empty List  (and returns another empty List, once it doesn't have any elements) and over a non-empty List by defining a pattern: name the first element of the List as x and the rest of the List as xs. Then, just performs the sum and concatenates with a recursive call.
I'm sure you'd have bad times trying to re-write the plus1 function using Imperative Style in 2 lines of code and still keeping it readable.
So, let's get started
There's a lot of content out there about Functional Programming, but the ones you shouldn't miss are:
- Principles of Functional Programming in Scala : it's good for the ones into Java that would like to get a taste of Functional Programming without getting rid of JVM. It covers the basic content.
- Paradigms of Computer Programming — Fundamentals : it's good for the ones who'd like to know how it is to learn how to program in a functional language. It uses an educational language called Oz, has a lot of exercises and you'll also get a taste of how it is to build data structures in functional languages. I think it presents good building blocks of Functional Programming which will help you with any other language in the future.
Unfortunately, they used to get open only at the end of the year. But you can follow the content and the videos, which are available on Youtube.
On the other hand, if you'd prefer textbooks, I strongly suggest you the following ones:
- Structure and Interpretation of Computer Programs
- How to Design Programs
- Concepts, Techniques, and Models of Computer Programming
The first 2 ones have the same curricula and will introduce you to the basics of Functional Programming and are very suited for beginners. The third one is the textbook of Paradigms of Computer Programming course and covers way more than Functional Programming. It is important to stress that those textbooks will only cover the beginning of it.
Furthermore, Chris Allen wrote a pretty good article on learning Functional Programming, it is called Functional Education. It presents a comprehensive list of resources to learn Functional Programming using Haskell, as well as strengths and weakness of each one. By following the resources Chris has recommended, you will be able to learn the principles and the advanced content (I am sure you've heard about monads) of Functional Programming and to get a little taste of how it is to build applications using it. (Thank you, Chris, for pointing out the article.)
Good luck in your Functional New Year. ☺