The most popular and widely accepted style of writing JavaScript in 2021.
But what is "functional style" and why is it so popular?
Let's take a look 🧵 👇
JavaScript is a multi-paradigm programming language.
This means that the language is open for programming in different styles, including object-oriented, procedural, prototypal, and functional.
By far, the most common styles you see are object-oriented and functional.
🔹 Imperative vs. declarative
👉 Object-oriented programming follows an imperative paradigm.
👉 Functional programming follows a declarative paradigm.
Let’s look at the difference.
Imperative programming focuses on how you want something done.
You alter the state of your program step by step.
Let’s say we want to iterate through a list of numbers and multiply them all by 2.
An imperative style would look something like this.
Simple and straightforward.
But there are two key observations we need to make here:
1. The function multiplyAll does not have a return value. 2. The original listOfNumbers array gets mutated.
When a function carries out a task in a deterministic way without changing its environment (changing state in its surroundings), we call it pure.
Since the function is not returning anything, we cannot determine the result based on the input. Hence, it’s not pure.
The function also alters (changes the state) of the input given as an argument. Hence, it’s not immutable.
These are common issues that lead to bugs and structures that are difficult to debug and maintain at scale.
Declarative programming focuses on what the end result will be.
How to obtain that result is less interesting, as long as obtaining it doesn't alter the state of your program.
Let’s rewrite it to follow a declarative style instead.
Well, isn’t this our lucky day?
JavaScript has a method on the Array prototype built in that does exactly what we need. It’s called map.
Let’s do a few observations again:
1. The function, map, has a return value. It’s a list with each element altered as specified in the callback function we provide.
2. The original listOfNumbers stays untouched. Hence, map is immutable.
On a lot of professional teams, this first example would be immediately rejected in a Pull Request.
The last one becomes way cleaner, easier to test, less prone to introduce bugs, and much more likely to be approved in a Pull Request on most professional teams today.
As it turns out, all the Array-methods (forEach, Map, Reduce, Filter, …) are following a declarative programming style.
Be careful about the pitfalls, though.
The Array-methods are only pure and immutable to the extent that you use them as intended.
The Array-methods doesn't magically turn anything into declarative, immutable, and pure code.
You still need to use them in a functional way, in order to reap the benefits of functional style JavaScript.
The same goes for utility libraries like lodash and date-fns, and UI libraries like React.
They are all built with a functional and declarative style in mind.
But they are only going to offer all its benefits if it’s used the way it was intended.
I’m my career as a consultant, I’ve often witnessed chaotic, careless - and sometimes tragically funny - mixes of styles piled on top of each other, which totally defeats the purpose of keeping consistent with conventions and coding styles throughout the application.
🔹 Avoid using classes
Ahh, classes. At the very root of object-oriented programming lies the concept of classes.
In JavaScript, classes are built on prototypes and are used as a template for creating objects.
They are - as in any other programming language - *inherently imperative* in their nature.
The use of classes has its place. It does make sense on some occasions.
But most often, you can avoid using them - and if you can, you should.
So generally, whenever you are about to use a class declaration, ask yourself if it’s really necessary.
Can you express the logic you need in a declarative way instead, using only functions? In 9/10 cases, I bet you can!
Take a look here 👇
It's one of those 9/10 cases. We can easily refactor this.
And if we can - we should 😎
Let's go.
Now, the code is declarative, easier to test, easier to debug, and treeshakable.
This means that build tools like Webpack and Rollup are able to remove the dead code of functions that may never be used in a specific case. It will result in a smaller bundle size of your code.
🔸 Create your own abstractions
So, we’ve covered some good rules of thumbs to follow.
But often enough, the code we write in our software is more complex than the examples we’ve looked at here.
There are cases where writing declaratively, avoiding the let keyword, not reassigning variables, not altering data in the surrounding scope of a loop, and so on, is simply going to produce tedious, verbose, and hard-to-read code.
Let’s take a hypothetical example 👇
Instead of turning all this around, we abstract that code into a function and then use it declaratively in the context where it’s needed.
I’ve seen this very often - it’s a great in-between solution.
Keep the code procedural, and then let the function return the final result.
Sure, as a reviewer, you could jump on this code and demand to refactor everything to use a strictly declarative pattern.
But there’s actually no point. The code does what it’s supposed to do - and most importantly, the function hasPassed is still pure.
The use of imperative code inside of the function cannot do any harm.
And now I’m able to use the function like this 👇
Nice, clean, and in a declarative way. That’s all I could ever ask for.
✅ PR approved.
As it is with everything - whether to use declarative or imperative code depends on the situation.
The world is not binary, and the same goes for computers! (...oh, wait? 🤔)
I recommend using a functional style as much as possible, and based on my experience, this is also the most popular choice in the industry.
Use imperative code with a bit of skepticism, and strive to avoid it when possible and when it makes sense.
I could go on and on here, but I'll leave it at this.
Bear in mind, that this is very opinionated.
For each of these examples, you will find developers in the industry who disagree.
And that's perfectly fine.
This thread is based on my impression from 10 years in the industry.
Whether you disagree or not, I hope you enjoyed this thread.
Was there something in particular that surprised you, or stood out?
I'm very curious to hear 😊
Also, take a second to like and retweet this thread for your own audience to see.
Thank you 🙏
• • •
Missing some Tweet in this thread? You can try to
force a refresh
🎯 The challenge
Write a function that — given a string — returns true if the string is a palindrome or false otherwise.
Let's look at 11 different approaches to solving this in JavaScript 👇🧵
👌 The definition
A palindrome is a word, number, phrase, or other sequence of characters which reads the same backward as forward, such as taco cat or madam or racecar or the number 10801.
- Wikipedia
According to the definition, we need to strip potential non-alphanumeric characters thus convert to lower-case.
So in all of the following solutions, we will be using a "clean" function to get a clean sequence of characters.
If you have never Open-Sourced a project before, the whole thing might feel very intimidating.
You probably fear what people will say? Will they throw shade at your project? Will it even be noticed at all?
You’re not alone in feeling this way. Believe me!
🔸 Finding a problem to solve
Most popular projects have a clear goal of solving a problem.
There are exceptions, but generally, great Open-Source projects consist of ready-made solutions to a problem that you can easily consume or incorporate into your own software.