Note: This is part of the “Javascript and Functional Programming” series on learning functional programming techniques in JavaScript ES6+. Checkout <Part 2> on First Class Functions.
I’ve always been about the bottom line. Uninterested in pseudo intellectual concepts, fancy terminology and hype. Instead, I always reach for the tools and technologies that help me ship code as soon as possible. This approach was initially productive — specifically when I was building smaller “proof of concept” applications.
Unfortunately, this approach did not scale. As I progressed as a developer I started feeling the law of diminishing return on my productivity. Setting up a project, and reaching basic functionality was fast. But the real problems started creeping up when my applications started growing in complexity. I found that as a project’s lifecycle advanced I was writing complex code. Code that I had written become harder to reason about. In order to understand it, I had to be extremely concentrated.
I had this itching feeling that a better, cleaner approach to developing software had to exist. I had heard whispers about functional programming, and how it allows developers to write more concise and elegant code. I was unknowingly exposed to functional paradigms and patterns for the first time while working with React and Redux. They both incorporated some of the principles, and I liked them. I read about FP — to my initial dismay I saw its paradigms were based on abstract mathematical concepts and that it was very prevalent in academia. Being that my goal is to ship products as fast as possible, this seemed like a counterintuitive approach to what I was trying to achieve. After 4 years in engineering school, I was pretty set on the opinion that academia only tackled theoretical problems, and was unlikely to ever help me in my day-to-day of building things.
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔
But FP kept haunting me. Elegant solutions and paradigms were sprinkled online in all my favorite open source projects, blog posts and tutorials. I put my skeptecism aside and started delving into FP.
Let’s just do this FP thang!
Although the concepts involve new jargon, and include a steep learning curve, I was amazed and really excited about this “new approach”. This series of articles shares my learning experience, and aims at extracting and summarizing the pearls of FP which enable a cleaner, more concise development experience. I will attempt to build an intuitive understanding of the patterns I discuss and frame the problems and the provided solutions as simply as possible, overstepping unnecessarily complex definitions. Learning FP has a reputation for being a bit daunting, but by breaking down the concepts into smaller bits, we will make the ideas easier to digest.
From the amazing Mostly Adequate FP Guide
The main difference in FP in comparison to other programming paradigms is a declarative approach (FP) versus an imperative one. Before we dive into formal definitions, let’s explore the differences by looking at an example.
Does this code seem evil? It should! What are the similarities between the methods above?
Let’s rewrite this snippet of code, but in a declarative manner.
.map? .reduce? What is this black magic?
First off, I promise that given the same input, these two methods produce the same output every single time.
A quick aside on the declarative snippet -
**.map()**
is a method accessible from every array in JS. The .**map()**
method creates a new array with the results of calling a provided function on every element in the calling array.
.**reduce()**
is a method that applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
Don’t fret about these just yet. We’re going to explore these handy array-native methods in depths in upcoming posts. But it is clear that the declarative snippet is more concise than the imperative one. It’s also a lot easier to read. Instead of instructing the program on which indexes I want it to access etc, I am simply supplying an expression to **.map()** and **.reduce()**
(an anonymous function in our case) which tells the program what I want it do to every element in the array.
This declarative approach is going to serve us well across the board by:
2. Composing shorter, expressive and concise code. After all, the less code we write the less we have to debug.
Most importantly, these tools and paradigms are going to help us achieve our (my) ultimate goal of shipping products faster. Check out the next post, where we discuss functions in JS, why they are special and how their characteristics enable functional programming.
You can follow me on Instagram, Linkedin and Medium.
And most importantly! I am creating these tutorials using Mindflow.ai. Mindflow creates smart summaries of your workflow (nearly) automatically. It makes documenting my work a breeze! Sign up for the alpha release here.