Eyes, JAPAN Blog > Functional programming in JavaScript

Functional programming in JavaScript

Mola BogdanGeorgii

この記事は1年以上前に書かれたもので、内容が古い可能性がありますのでご注意ください。

Introduction.

The appearance of JavaScript (JS) was a big historical milestone in the evolution of the internet. Starting as something not serious like “Hey look, I can change the colour of a page on click!” it became to be significantly more serious and ubiquitous than it was expected. After every release of a standard, JS get more power in the context of the OOP paradigm. But this time I would like to share some important basics of techniques that belong to the Functional Programming paradigm.

What is Functional Programming is up to?

Most likely anyone with programming experience has at least a general idea of this development methodology. But let us state major dogmas.

Pure functions.

If there are pure functions, can be there dirty ones?.. 🙂 The function can be pure if the result of the function depends only on incoming arguments. Let’s move to an example:

The purpose of mentioned above function is mega trivial, which return half of the input value. What is crucial here is that it doesn’t matter how much we call a function with a value of 4, it will always return 2. It is absolutely pure function. What about “dirty” functions?

Looks totally innocent and trivial, however, if someone will use such an approach, adepts of functional programming will definitely accuse such a person of heresy. The issue here is anyNumber variable, the state of which can be changed outside of function semantical scope. It will return 4 always if nothing will change the variable. Such change is also called a side effect of function and is considered a bad practice. The property which guarantees the same behaviour for the same input in computer science (and math) is called idempotence. 日本語.

The main pros of following this concept are:

  • Easier to maintain and extend
  • Easier to test

The cons are the with harder instead of easier 🙂

Stateless.

According to the concepts of functional programming, it is a good practice to avoid states. Let’s consider the example below.

These examples basically the previous ones, but the goal is to demonstrate a stateless approach. In addition, to be not pure function left one also has a changeable state which is a variable number, we already know that this can make tracking of whats going on in the program difficult. Additionally, the left function has extremely limited application. In the case of the right example, the function does not change state and can have a lot of applications (increase the value by one for any input number). The next concept is based on this principle

Immutability.

The JavaScrip reference that describes standard methods for string and arrays at the very beginning of the description for each method states whether input will be changed or function returns a copy. So JS strive to avoid changing objects by design. Why so? Let’s have a look at the example below.

At first glance, the absolute regular operation has been done and the presented code is working, however, the function does modifications of car objects. In other words, it mutates the original object. How did it suppose to be done?

The difference here is providing a new object instead of mutating an old one. What’s the point here? The answer is sustaining control over the workflow of code. Uncontrolled changes on a big scale soon or later will bring bugs that will be hard to track down, after tracking down refactoring will be necessary, which is the last thing you want to do. To underline the importance of such an approach you can check the following library immutable-js which is aimed to assist with that this concept.

First-class functions.

This tricky term represents the feature of language that allows assigning function to a variable or passing functions as arguments of other functions. As before, let’s check out an example.

Usually, the function that has been passed as an argument is called “callback“. In that example, a callback helps to make a new function based on another. Below is another interesting use case.

Basically, we made a function that accepts greeting phrases and combines them with some arguments that will be received in future. Such an approach allows creating a function that not just return another one, but configure returned function. This is a powerful tool for making reusable and concise code! That’s how closure works! As a bonus, the last two example shows another important technique higher-order functions, functions that return a new function or accept one as an argument.

[If a dollar sign based statement looks unfamiliar, it is called template strings, which is a very useful syntax. Feel free to make checking it as homework.]

Composition.

This paragraph is not just about composition as a principle, but also composing previously described concepts 🙂

Composition is one of the foundation stones of functional programming. However, it is quite simple and takes roots from some general principles of engineering. According to this concept, it is necessary to strive to functions that have a very single responsibility. In other words high modularity. It supports high code reuse but also brings some specifics. Let’s imagine we need to perform several modifications of string: make string uppercase, add exclamation sign and repeat 3 times. This task is easy to decompose in the following way using mentioned before tricks.

Just a chain of functions combined in one call.  Simple and concise code. Is it? It follows an idea, but since the talk is within JavaScript, let’s fully use the features of the language.

It would be nice to have some function that combines calls for us. Something that can be used like this and support readability:

And here is a possible way:

Oh, this highest-order function! It accepts variable length arguments (… syntax), returns the second function that takes the initial value (in our case it’s ‘hello’), the second function takes arguments from top-level (funcs) and applies built-in function JavaScript method for arrays reduceRight, which basically process the content of array into a single value using (drum roll) function provided from the input. Without knowledge of the built-in method, it may be not so obvious that the result is a variable that accumulates output and func used for storing elements for the current iteration. But it is shown how combining good practices and applying features of language helps to write concise and readable code.

P.S. Unfortunately mentioned above practises considered as good, but they are not 100% key to success. For example, in some cases, super shortcode can be not so easy to read and it is necessary to take into account the convenience of other development team members. As always, the experience will help to understand in which cases which approach will do the trick. Let’s not be fanatics and use appropriate tools according to the task.

Comments are closed.