Point-Free Style in JavaScript

Point-Free Style in JavaScript

Daily short news for you
  • Manus has officially opened its doors to all users. For those who don't know, this is a reporting tool (making waves) similar to OpenAI's Deep Research. Each day, you get 300 free Credits for research. Each research session consumes Credits depending on the complexity of the request. Oh, and they seem to have a program giving away free Credits. I personally saw 2000 when I logged in.

    I tried it out and compared it with the same command I used before on Deep Research, and the content was completely different. Manus reports more like writing essays compared to OpenAI, which uses bullet points and tables.

    Oh, after signing up, you have to enter your phone number for verification; if there's an error, just wait until the next day and try again.

    » Read more
  • I just found a quite interesting website talking about the memorable milestones in the history of the global Internet: Internet Artifacts

    Just from 1977 - when the Internet was still in the lab - look how much the Internet has developed now 🫣

    » Read more
  • Just thinking that a server "hiding" behind Cloudflare is safe, but that’s not necessarily true; nothing is absolutely safe in this Internet world. I invite you to read the article CloudFlair: Bypassing Cloudflare using Internet-wide scan data to see how the author discovered the IP address of the server that used Cloudflare.

    It's quite impressive, really; no matter what, there will always be those who strive for security and, conversely, those who specialize in exploiting vulnerabilities and... blogging 🤓

    » 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

5 profound lessons

Every product comes with stories. The success of others is an inspiration for many to follow. 5 lessons learned have changed me forever. How about you? Click now!

Every product comes with stories. The success of others is an inspiration for many to follow. 5 lessons learned have changed me forever. How about you? Click 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...