Point-Free Style in JavaScript

Point-Free Style in JavaScript

Threads
  • Good news to start the day. GitHub has just widely announced GitHub Models to everyone. If you remember, more than 2 months ago, GitHub had a trial program for using LLMs models, and in my case, it took a month to get approved for use. Now, they have given everyone with a GitHub account access, no registration needed anymore 🥳

    GitHub Models is currently a lifesaver for me while building this blog 😆

    GitHub Models is now available in public preview | Github Blog

    » Read more
  • I came across a repository that uses Tauri and Svelte to rewrite an application like the Task Manager on Windows or the Monitor on Mac. I was curious, so I downloaded it and was surprised to find that the app is only a few MB in size and loads quickly. The app itself is also very smooth

    » Read more
  • I've noticed that whenever I'm enthusiastic about reading, I tend to be lazy about writing. This week, I'm reading three books at the same time, or rather, two and listening to one.

    The most haunting book so far is 'The Black Ocean' - a collection of 12 stories about people struggling with depression. I have a strong mental fortitude, but after reading just two stories, I felt suffocated and restless.

    The next story brought some relief, as the protagonist managed to control their emotions. However, as I continued reading, I felt like I was being choked again. It's terrifying, and I couldn't close my eyes while listening.

    One sentence that particularly resonated with me is when the parents of someone struggling with depression ask why they're like that, and the person responds, 'How am I supposed to know? It's like asking someone why they're sick. Nobody wants to be like that!'

    » Read more

The Issue

Have you ever seen code like this before?

fetch('https://api.example.com/endpoint')
  .then(toJSON)
  .then(handleResult)
  .catch(handleError);

My first encounter with this style left me quite puzzled. toJSON, handleResult, handleError – what are they here? Are they functions, and if so, where are their parameters? How can they run without ending with () to make a function call? Or at least, where are their input parameters?

Many questions swirled in my mind, but at that time, there was no one to explain it to me. What you encounter frequently becomes familiar, so I started emulating this style, implicitly thinking, "Oh, I'll just write it like this, and it will work."

It wasn't until later that I understood that this style is called Point-Free. So, if it was initially unclear, why do people still use it? Is there something mysterious or interesting about this way of writing code? Let's find out in the following article!

Point-Free Style

Point-Free style means not specifying arguments for each function application. The term "Point" refers to a function's parameter, and Point-Free means there's no "place" for those parameters. This model aims to make readers focus on what a function does, not caring about the specific names of its parameters.

Returning to a simplest example, we create four functions that, just by looking at them, you can tell what they do:

const testOdd = x => x % 2 === 1;
const testUnderFifty = x => x < 50;
const duplicate = x => x + x;
const addThree = x => x + 3;

Then, we apply a series of transformations to a list of numeric data:

const myArray = [22, 9, 60, 24, 11, 63];

const result = myArray
  .filter(testOdd)
  .map(duplicate)
  .filter(testUnderFifty)
  .map(addThree);

Looking at the data flow, from top to bottom, we filter out odd numbers, double them, filter again for numbers less than 50, and finally, add 3 to all of them.

With this style, all you see are function names, even in the data flow. This style achieves conciseness, but you have to choose meaningful, understandable function names.

Returning to the opening example, if written in the conventional way, your code might look like:

fetch("https://api.example.com/endpoint")
  .then((res) => res.json())
  .then((resJSON) => {
    const { data } = resJSON;
    const dataFiltered = data.filter((item) => item.active === true);
    return dataFiltered;
  })
  .catch((err) => {
    if (err instanceof RangeError) {
      throw new RangeError("The number is outside the range");
    } else if (err instanceof EvalError) {
      throw an EvalError("The code could not be evaluated");
    }
  });

A bit too much to read and understand, right? Let's "refactor" it a bit:

const toJSON = res => res.json();
const handleResult = data => data.filter(item => item.active === true);
const handleError = err => {
  if (err instanceof RangeError) {
    throw new RangeError("The number is outside the range");
  } else if (err instanceof EvalError) {
    throw an EvalError("The code could not be evaluated");
  }
};

fetch("https://api.example.com/endpoint")
  .then((res) => toJSON(res))
  .then((resJSON) => handleResult(resJSON))
  .catch((err) => handleError(err));

Better, but there's still redundant code. Let's make it Point-Free:

fetch('https://api.example.com/endpoint')
  .then(toJSON)
  .then(handleResult)
  .catch(handleError);

Pros and Cons

The most apparent advantage of Point-Free is that it focuses on functions rather than data, making code shorter and easier to read if you choose good function names. When combined with libraries following the Point-Free style, like ramda.js or lodash/fp, which provide numerous utility functions, it can create consistency in your project.

The second example, after being fully converted to ramda.js, might look like:

const R = require('ramda');

const isOdd = R.pipe(R.modulo(R.__, 2), R.equals(1));
const isUnderFifty = R.lt(R.__, 50);
const double = R.multiply(2);
const addThree = R.add(3);

const handle = R.pipe(
  R.filter(isOdd),
  R.map(double),
  R.filter(isUnderFifty),
  R.map(addThree)
);

const myArray = [22, 9, 60, 24, 11, 63];
handle(myArray);

However, what's an advantage for some might become a disadvantage for newcomers or those unfamiliar with the Point-Free style. It can be harder to understand or take more time to approach.

Conclusion

Point-Free is a programming style that focuses on function names and disregards the importance of arguments. With this style, we concentrate on the data flow rather than the logic behind it. For beginners, Point-Free can be challenging to read or understand. But once you get used to it, you'll find it extremely useful.

or
* The summary newsletter is sent every 1-2 weeks, cancel anytime.
Author

Hello, my name is Hoai - a developer who tells stories through writing ✍️ and creating products 🚀. With many years of programming experience, I have contributed to various products that bring value to users at my workplace as well as to myself. My hobbies include reading, writing, and researching... I created this blog with the mission of delivering quality articles to the readers of 2coffee.dev.Follow me through these channels LinkedIn, Facebook, Instagram, Telegram.

Did you find this article helpful?
NoYes

Comments (0)

Leave a comment...