On 24th of October 2019 I made my first speech at the Codemotion conference in Milan, Italy.
I talked about functional programming and how it can make our life easier when dealing with complex real world problems such as maintainability, scalability and error handling.
A lot of people asked me "how would you recommend to begin with FP?", and the answer is really easy.
If the same question was asked in the ’80s, my answer would be completely different. But today, as frontend development is becoming more and more complex, I’d just recommend to start with functional TypeScript.
Why? Let’s find out!
At its core, Functional Programming forces you to write pure function for a simple reason: we need to get deterministic results out of our computations.
For instance, if we’re dealing with a function that depends on the user’s input… how many things could go wrong? User could insert a wrong or incomplete input, connection may fail, sending data to the server may require an HTTP request that may fail for a number or reasons… we’re never sure that everything can go as we imagined. How the heck can we get a deterministic result out of this mess? putting
try/catch everywhere? Creating a huge
if/else control structure?
We know a more elegant way.
In the “Handling the try/catch and if/else hell” article we’ve seen how monads can help us to improve our code flow and resiliency.
- Data may cause an error? Let’s use the Either monad. It will always return two values:
- Data may be
undefinedfor some reason? Maybe monad to the rescue! Our data will be wrapped inside
Just(<data>)if exists, otherwise we’ll have just a
Nothingvalue to be handled. No more
- Data exist but we have one or more copies of it? List monad will be your friend!
- Data depends on a state? State monad will help you a lot!
and so on, and on, and on!
What’s the point of this? We’ll always get predictable result out of uncertain operations.
At the beginning I’ve said that I’d recommend Functional Typescript. But do we really need types in order to make our code functional?
No, of course. Erlang, Elixir, LISP, just a short list of dynamic-typed functional languages.
These language have some great reasons to be dynamic-typed, and they often offers some analysis tools such as Erlang’s Dialyzer, which is “a static analysis tool that identifies software discrepancies, such as definite type errors, code that has become dead or unreachable because of programming error, and unnecessary tests, in single Erlang modules or entire (sets of) applications”.
They also helps us to read our code more easily.
How many times did you run your JS code with a debugger because of type errors? And how hard it was to identify that annoying type error in your code?
Well, it might be trivial, but with Flow or TypeScript, you’ll never get these errors again.
When writing in strongly-typed functional languages such has Haskell or Idris, you have a better look of your data.
In Functional Programming, functions describes your data.
Types describes your data too.
You always have focus on how your data is being manipulated during your computations.
Why starting with functional frontend?
For a simple reason: you’ll immediately see the results.
Let’s say for a moment that we’re writing a blogging platform such as WordPress from scratch using Laravel, Spring or Ruby on Rails.
User is logging in and an error occurs on the backend. No problem, we just send an error to the frontend and the user will be warned.
Our backend fluxes are often well defined and we’re used to handle these errors.
We can start to handle all these cases with a minimum effort adopting a new way of programming our frontend applications.
Pure functions allows us to reuse our code easily.
A more modular codebase means that we can define our functions once and reuse them whenever we want. We don’t need to write private class methods that only works inside a certain class, and we don’t want to rewrite some methods just because they depends on a hidden state (so they won’t work outside a certain class).
We want our functions to be as reusable as possible, so our codebase will grow without adding kilobytes of duplicate functions to our bundle.
When writing server-side applications, you probably won’t feel the need for a functional codebase until your software begins to show some scaling issues.
There are tons of cases where passing from an OOP architecture to a functional one can reduce the number of servers drastically.
Of course, FP advantages are not just about scaling, but code maintainability, testing, modularity, error handling (and so on).
Frontend also has some interesting cases (as we saw earlier) where FP could actually make a difference.
Once you’re confident with functional JS, the switch to other languages will be a lot easier!