Functional Programming tends to scare people with the academic terms borrowed from Category Theory to describe interfaces known as “Algebraic Structures”.
Functional Paradigm was adopted through languages like Erlang, R and even the most recent ML, Haskell, OCaml, F # and Elixir. Already our beloved Javascript wasn’t designed to be a functional language. Fortunately, JavaScript is well-suited for the task, thanks to first-class, high-order functions and proper tail-call optimization provided in ES2015.
The more abstract a concept is, the harder it is to understand. Interfaces are abstract in nature. The more abstract they are, the more powerful they become, because they allow us to solve a wider range of problems apparently unrelated to a surprisingly small set of patterns.
The purpose of functional programming is to allow us to think less and write more descriptive codes.
The good news is that you don’t need to turn the key and everything is working in your head. You can apply functional approaches as you learn. I’ve been slowly studying this paradigm, and every day I see new ways of solving problems and each refactoring makes the code much more enjoyable.
Learning new programming paradigms is like learning a new instrument. After each note learned we increase our power of expression.
In my day-to-day work I use Functional Paradigm infrequently, but this foundation allows me to see problems in a different way and even to combine functional concepts with other paradigms such as Object Orientation. This has been a trend in the evolution of languages, in other other, we can unite the best of worlds. The example below in Typescript/Angular shows the union of functional concepts like map and Object Guidance concepts like the use of classes.
Multiple paradigms help you apply different ways of thinking about solutions to problems because solutions vary across languages.
Ultimately we will see that a stateless application is useless. But we always need to carefully select the points in the code where we allow the mutation to occur. Most of the internal parts of the code should strive to be immutable and therefore testable. The more mutations you can eliminate, the better.
Chip makers are on the atomic limits of transistor miniaturization. As a result, clock rates have not increased since 2004.
Multi-core is currently the preferred strategy for improving speed. Routines with shared mutable state cannot be distributed in parallel across multiple cores because they are not thread-safe.
As a suggestion follows Robert Martin’s lecture about this subject. Just note: an “assignment statement” is totally benign a “reassignment statement” is problematic.
When you reassign (mutate) a variable you are introducing state change to your application. To reproduce a complex bug you often need the sequence of computations that lead to the failure. When you mutate variables you are throwing away that sequence.
Whenever you need to model a state change, you pass the previous value to a function that returns a new value. Don’t change the old value just return a new one.
Although JavaScript doesn’t support immutable objects, we can still write our code in a way that avoids most mutations.
Write functions that return changed copies instead of changing the properties of the specified object.
Objects are references, if we avoid changing their properties we avoid situations of unclear states. Also our finished code will be simpler to understand and easier to test.
It seems a lot of tedious work to avoid mutation with the above examples but the fact JavaScript doesn’t have built-in support for immutable objects makes this very difficult for us. Time to get help!
Facebook’s Immutable.js is a small library that helps us keep our state immutable. There are other libraries that work in a similar way (Mori, seamless-immutable, acient-oak), but for this article we limit ourselves to Immutable.js.
Immutable.js provides many persistent immutable data structures including:
_List, Stack, Map, OrderedMap, Set, OrderedSet and Record_
Or in form of code:
Although we lose direct access to object properties, we can now focus on our goals, rather than fighting against mutations.
There is also the eslint-plugin-immutable plugin to disable all mutations in JavaScript. The readme mentions a lot of React/Redux, but you can safely use the plugin without both.
The plugin adds three rules:
This is the main reason why immutability makes sense. To be thread safe, you don’t need to lock anything that is not changed. In Javascript there is no real concurrency. Instead, we have an event loop. So forget it.
Changing object properties is considered a mutation, in other words, a side effect by definition. We all learn that we should avoid side effects at all costs. We don’t need to examine the implementation of a function if it has no side effects. Our code gets easier to reason about and will be more predictable and more testable.
There are times when you need to stop and think if you are dealing with a value or a reference. Immutable objects are always values. This is one of the fundamental principles of functional programming. If I pass the value to a function, I can promise that it stays the same forever.
If you have objects that change very often, it isn’t a good idea to create a new instance for each change. This is especially true for games and simulations where this happens several times per second. I’m not saying that you can’t use immutability in games, but it is easier to fall into performance problems than in mutable objects.
If you have a huge data tree stored as an immutable container, I recommend checking your memory consumption. Of course, garbage collection kills all old objects, but copying large objects still has its price (Most frameworks on the market already handle this kind of problem very well).
In general, it is a pretty reasonable language design choice to take into consideration are the immutable types of data, since there are some problems that are simply not well modeled when everything is immutable. In most situations the advantages of immutable types vastly outweigh the disadvantages and they are better than the alternatives and lead to better code and faster executables overall.
As said at the beginning of the post, we don’t have to turn on a key to changing paradigms completely, we can start implementing immutable types gradually entering into more complex and useful patterns according to the need of our application. To end this post I leave @jamesiry’s tweet as a reflection.
To be, or not to be a “Functional Programmer”, that is the question 😂
fantasyland/fantasy-land_fantasy-land — Specification for interoperability of common algebraic structures in JavaScript_github.com
haskellcamargo/js-real-world-functional-programming_js-real-world-functional-programming — Tips and guidelines for real world functional code-bases in JS_github.com
getify/Functional-Light-JS_Functional-Light-JS — Pragmatic, balanced FP in JavaScript. @FLJSBook on twitter._github.com
Functional programming paradigms in modern JavaScript: Immutability_This is the second chapter in a series of articles on practical Functional Programming paradigms. If you haven’t read…_hackernoon.com
Andrea Magnorsky on Paradigm Shifts and the Adoption of Programming Languages_On this podcast, we talk with Andrea Magnorsky, who is a tech lead at Goodlord on their engineering squads; she has a…_www.infoq.com
functionaljava/functionaljava_functionaljava — Functional programming in Java_github.com