What is a Curry function? A delicious "curry" dish and how to enjoy it?

What is a Curry function? A delicious "curry" dish and how to enjoy it?

Daily short news for you
  • For a long time, I have been thinking about how to increase brand presence, as well as users for the blog. After much contemplation, it seems the only way is to share on social media or hope they seek it out, until...

    Wearing this shirt means no more worries about traffic jams, the more crowded it gets, the more fun it is because hundreds of eyes are watching 🤓

    (It really works, you know 🤭)

    » Read more
  • A cycle of developing many projects is quite interesting. Summarized in 3 steps: See something complex -> Simplify it -> Add features until it becomes complex again... -> Back to a new loop.

    Why is that? Let me give you 2 examples to illustrate.

    Markdown was created with the aim of producing a plain text format that is "easy to write, easy to read, and easy to convert into something like HTML." At that time, no one had the patience to sit and write while also adding formatting for how the text displayed on the web. Yet now, people are "stuffing" or creating variations based on markdown to add so many new formats that… they can’t even remember all the syntax.

    React is also an example. Since the time of PHP, there has been a desire to create something that clearly separates the user interface from the core logic processing of applications into two distinct parts for better readability and writing. The result is that UI/UX libraries have developed very robustly, providing excellent user interaction, while the application logic resides on a separate server. The duo of Front-end and Back-end emerged from this, with the indispensable REST API waiter. Yet now, React doesn’t look much different from PHP, leading to Vue, Svelte... all converging back to a single point.

    However, the loop is not bad; on the contrary, this loop is more about evolution than "regression." Sometimes, it creates something good from something old, and people rely on that goodness to continue the loop. In other words, it’s about distilling the essence little by little 😁

    » Read more
  • Alongside the official projects, I occasionally see "side" projects aimed at optimizing or improving the language in some aspects. For example, nature-lang/nature is a project focused on enhancing Go, introducing some changes to make using Go more user-friendly.

    Looking back, it resembles JavaScript quite a bit 😆

    » Read more

The Problem

For every programmer, writing reusable code is essential. Each person has their own ways of achieving this, such as creating libraries of useful code snippets. But in this article, let's focus more on a micro-level approach, at the function level.

What is a Curry function?

The concept of a curry function is quite simple - it is a regular JavaScript function that takes multiple arguments as a series of single-argument functions. For example:

function sum(a) {
  return function add(b) {
    return a + b;
  }
}

const add1 = sum(1);
const result = add1(2);
console.log(result); // 3;

// Alternatively, we can write it more concisely as:  
const result =  sum(1)(2);
console.log(result); // 3

Oh, the syntax seems unfamiliar, doesn't it? So what benefits does it bring?

Why Curry function?

There are two things that curry functions can bring:

  • Smaller functions can express the problem more clearly and can be easily reused without clutter.
  • Functions can be used repeatedly.

Let me provide examples to clarify these two points.

Smaller functions express better

In the first example, I have an array of objects with id and name, and I want to extract only the id:

const objects = [{ id: 1, name: "A" }, { id: 2, name: "B" }, { id: 3, name: "C" }];
const ids = objects.map(function (o) { return o.id; });

It looks simple, right? But there is a problem with function (o) { return o.id; } - it works, but it can be better. Let's improve it:

function get(attr) {
  return function getAttr(obj) {
    return obj[attr];
  }
}
const ids = objects.map(get("id"));

get is a curry function. It takes an attr to serve the purpose of extracting a specific attribute and an obj as the object to be extracted.

You may find the syntax in ids a bit confusing, so let's recall the map function in JavaScript:

Array.map(function (i) { return i; });

.map takes a function as a parameter, which has access to each element in the array for processing.

In other words, this is actually what ids does:

const ids = objects.map(function (o) { return get("id")(o); });

Now do you understand? So here's a question for you: if I want to reuse the function that extracts id from objects, how would I do it? Is it like this:

function getIds(objs) {
  return objects.map(get("id"));
}

getIds(objects);

It seems to work, but it can still be improved. Why don't we apply curry function to create a function called "map" that loops through the elements in an array?

function map(func) {
  return function exec(value) {
    return value.map(func);
  }
}

const getIds = map(get("id"));
getIds(objects);

Here, I can see that if basic functions are curried, I can easily create a new function that performs a different functionality from them. And another thing is that the code is written in a very readable manner, making it clear what it does at first glance.

Translucent functionality

One advantage of curry functions is that they allow your code to focus more on the specific functionality rather than being a regular function. In the examples above, using curry functions makes the code look more understandable:

fetchData()
  .then(JSON.parse)
  .then(function(data){ return data.posts })
  .then(function(posts){
    return posts.map(function(post){ return post.title })
  });

You may have a different way to write it, but in this case, I want to emphasize that using curry functions will make the code look more understandable:

fetchData()
  .then(JSON.parse)
  .then(get("posts")
  .then(map(get("id")));

Thanks to the benefits of curry functions, there are quite a few supporting libraries such as the curry and curry functions in Ramda, a famous library for functional programming.

Summary

Curry functions are a way to "play" with functions, making it easier to understand and utilize the benefits they bring. If you find it fascinating, try applying it to your next project starting from now.

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