Functional Programming is easier than you think
In the last few months, I decided to dedicate my free time learning this strange and so hyped paradigm.
After some time, I found it to be the best way to write rock solid and battle-tested code.
Why Functional Programming?
Because it makes things easier. That’s why!
Ok, let me explain that concept.
Imperative programming works much more like our brain do. Here is an example:
In this example, we are calculating a factorial of a given number.
So basically, the compiler is reading our code like this:
- I’m declaring three integer variables which are respectively equal to
- I’m printing on the screen an instruction for the user.
- I’m getting the user response, which will be stored in the
- Given that
iis equal to
nis equal to (as an example)
5, for each integer number between
5, set the variable
factorialequal to the product of the current integer value and the current
- Print the result on the screen.
Pretty easy, huh? Now let’s see a the functional counterpart:
Is this example really complex? Nope.
What does the compiler read?
- Factorial of
nis equal to the product of each number between 1 and
Pretty straightforward! But I believe that it’s not fair to compare this Haskell approach with the C approach.
The interpreter reads the following:
- Define a new function called
factorial, which accepts one argument.
nargument is equal to
1, then return
- Else, return the product of
nand the returning value of the function itself, given the argument
n could be a String or any other data type and the function would break.
n could be a negative integer and the function would break.
So, these cases drives us to an amazing functional programming feature called
currying (aka function composition).
In mathematics, function composition is the pointwise application of one function to the result of another to produce a third function. For instance, the functions f : X → Y and g : Y → Z can be composed to yield a function which maps x in X to g(f(x)) in Z.
Ok I made it a little verbose just to make it more understandable.
Anyway, the code is pretty clear:
- Once the main function as been defined, print a directive to the user
- Get the user input and pass the result as the first argument for the following method
get_integermethod, pattern matches agains the given argument and returns an integer, so now we are sure that it is a positive number
get_integermethod will send the result directly to
calculate_factorialmethod, which will send the result to
IO.putsmethod who’ll print the final number on the screen.
Once again, where is the complexity?
We’ve wrote an amazing example without using loops (only recursion), declaring variables and using immutable data, and I think that this little example is way easier using a FP approach!
Want other examples?
The function above, which is written in Scala, takes an array of integers and returns the sum of the odd ones. I find this example really easy and beautiful! No use of loops, variables, mutations etc.
How would you implement this in a imperative way?
Another small example, list replication.
I have an array of integers and I want to replicate them 3 times.
Input: [1, 2, 3, 4]
Output: [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
How can I achieve that without loops, mutations and variable declaration?
Easy and straightforward!
But Functional Programming languages are not production ready!
Developers are not production ready. Functional programming languages are.
- Whatsapp is currently serving more than 1.2 billion users worldwide thanks to Erlang, a functional programming language with the best and most solid concurrency model ever created. (source)
- Telecom is running systems with 99.999999999% (nine nines) uptime (0.631 seconds of downtime per year) for over 20 years thanks to Erlang. (source)
- Facebook is using Haskell in production for fighting spam. (source)
- Redux, a pure functional implementation of the Flux architecture, is used in production by thousand of websites/webapps using React.js.
- Twitter switched from Ruby (object oriented) to Scala (functional) in order to fix its scaling issues. (source)
I could continue all day long, but these are great examples of how functional programming paradigm is used in production by industry leaders.
But Functional Programming is hard to write and my productivity will be reduced
That’s probably one of my favorites points.
Functional Programming helps you a lot by splitting your codebase into little functions. Advantages?
- Functions can be tested one by one
- Functions are predictable. Given an input, we can predict its output
- No side effects. Given the fact that we are not declaring any variabile (only constant values or expressions, depends on the language), we don’t have any value which mutates during the execution. This will help us to keep track of our state and won’t drive us to runtime exceptions.
- Concurrency is way easier. Some languages (Haskell, Erlang, Elixir, Clojure) will come with concurrency out of the box.
- Functional programs are often shorter that the imperative/object oriented ones. An example from this HackerRank problem:
Haskell code is shorter, easier to debug, to extend and to maintain.
You talked about concurrency… how is it managed in a FP fashion?
Out of the box! There is an amazing article which talks about this:
A functional program is ready for concurrency without any further modifications. You never have to worry about deadlocks and race conditions because you don’t need to use locks. No piece of data in a functional program is modified twice by the same thread, let alone by two different threads. That means you can easily add threads without ever giving conventional problems that plague concurrency applications a second thought.
Pretty nice, isn’t it?
Which FP language should I start with?
That’s how you actually print “Hello World” in Haskell 😂
Some people may be scared because FP paradigm is completely different from any other programming style.
Depending on your previous experience, the answer may be different.
New to programming?
Go with Haskell.
Without any previous programming experience, Haskell is an amazing playground. You won’t be tempted to declare variables, loops or any other imperative thing.
Once you feel ready, you can go with OCaml (highly used at Facebook these days) or Clojure (https://clojure.org/community/companies)
Go with Scala!
You will still use all the amazing and rock solid Java libraries and you will still compile JVM bytecode.
Need to build an high-concurrency solution?
Go with Elixir or Erlang.
Both languages compiles BEAM bytecode.
BEAM is the oldest and most solid virtual machine out there. It will scale insanely well and will guarantee an incredible reliability.
I want to write rock solid frontend code.
ELM and PureScript to the rescue! They’re both great programming languages highly influenced by Haskell.
I am a Microsoft .NET guy.
In that case, F# is an amazing solution. Don’t get me wrong, it would be an amazing solution anyway, but I found F# to be really really great in the .NET context.
Anyway, a bit of Haskell culture will help you a lot solving some problems in a pure FP way, so I highly recommend to get your feet wet with this incredible language!
Getting started with Functional Programming
If you want to get started with Functional Programming, I would recommend a lot the following books:
- Real World Haskell (O’Really) · Link
- Introducing Elixir (O’Really) · Link
- Real World OCaml (O’Really) · Link
- Functional Web Development with Elixir, OTP and Phoenix (The Pragmatic Bookshelf) · Link
- Learn You Some Haskell for Great Good · Link
- Learn You Some Erlang for Great Good · Link
- Functional Programming & Haskell · Link
- Teaching Functional Programming to Noobs · Link
- Functional Programming for Dummies · Link
- Functional Programming for People who Hates Maths · Link
Functional Programming will not solve all your problems by itself.
You may wish to continue using your Object Oriented language of choice and that’s completely fine!
I know a lot of people who is making awesome and rock-solid products in Java, Ruby, Python and even PHP.
Functional Programming, by the way, can help you a lot approaching problems in a different way. It will help you to see solutions from another perspective which may be the best for that specific case.