Point-Free Style in JavaScript

Point-Free Style in JavaScript

Daily short news for you
  • Zed is probably the most user-centric developer community on the planet. Recently, they added an option to disable all AI features in Zed. While many others are looking to integrate deeper and do more with AI Agents. Truly a bold move 🤔

    You Can Now Disable All AI Features in Zed

    » Read more
  • Today I have tried to walk a full 8k steps in one session to show you all. As expected, the time spent walking reached over 1 hour and the distance was around 6km 🤓

    Oh, in a few days it will be the end of the month, which means it will also mark one month since I started the habit of walking every day with the goal of 8k steps. At the beginning of next month, I will summarize and see how it goes.

    » Read more
  • It's been a long time since I've read such a heartfelt article The many, many, many JavaScript runtimes of the last decade. In the article, the author recounts the journey of the development of the JavaScript runtime environment, noting that today we have and are seeing JavaScript present in many areas. Additionally, the author also touches on a lot of peripheral knowledge; just a little reading opens up so many new discoveries 🤓

    » 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.

Premium
Hello

Me & the desire to "play with words"

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

Have you tried writing? And then failed or not satisfied? At 2coffee.dev we have had a hard time with writing. Don't be discouraged, because now we have a way to help you. Click to become a member now!

View all

Subscribe to receive new article notifications

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

Comments (0)

Leave a comment...