Functional Programming with JavaScript in 3 Steps
Pure functions, immutability & declarative pattern… you’re in for a treat.
The updated article was moved here since Medium keeps breaking/removing code snippets.
Functional programming has its roots in lambda calculus, a mathematical concept dating back to the 1930s. That might sound daunting, but it’s really not. Without going into the mathematical theory, these principles will introduce you to some of the wonders of functional programming and its benefits for your software.
Let’s get right into it!
Favor Pure Functions
A function is pure if:
- it always returns the same output for the same input
AND
- it has no side effect
In other words, pure functions map inputs to outputs.
The caller and the pure function may only communicate via arguments and return value:
Pure functions are predictable, easy to debug and super easy to test. Also, because they are referentially transparent, they allow for a bunch of optimization techniques such as memoization (which is used to speed up repeated evaluations by caching function results).
Not every function can be pure. Some are inherently impure when dealing with I/O, randomization, networking, databases, etc. Nevertheless, these concepts can and should be moved to the outer edges of your software in order to have a larger functional coverage and thus a simpler core.
Favor Immutability
In JavaScript, all primitives (boolean, string, etc.) are immutable. While it is not the case of objects & arrays, we can choose to treat them as if they were.
When immutable, an object or array cannot be modified after it is created.
If we wish to modify it, we must duplicate it and assign it a new variable:
Since they have one and only one state, immutable objects & arrays cannot be made invalid by change and they avert side effects.
Immutable data is also thread-safe and failure atomic.
Bonus: because immutable objects & arrays only require a reference check instead of a deep compare to detect “change”, they allow for fast change detection which plays a major role in efficient state management (think React applications).
Favor Declarative Patterns
- Declarative programming describes WHAT we want to achieve.
- Imperative programming describes HOW we want to achieve it.
In other words, imperative programming describes explicit step-by-step instructions while declarative programming consists of a sequence of declarations:
A declarative pattern puts the focus on the problem domain and not the implementation details. It typically leads to a much more concise and much less error-prone code. Besides, it is much easier to read and reason about.
By the way, did you notice how shortNames also became immutable in the process?
JavaScript has a ton of useful higher-order functions such as map, filter, reduce, etc. These are musts when writing declarative code so use them extensively!
To wrap up
You get to add functional programming to your tool belt! Now, you can follow these principles as you see fit; see what works for your project and what doesn’t.
All in all, this article barely scratched the surface, but hopefully shed some light on functional programming and tickled your curiosity.
If you have any questions, don’t hesitate to ask and I’ll answer as best as I can!