How is currying usefull?

How is currying usefull?
I mean, how would you use it in a more complex problem or what use-cases it can reach a better function usability than a normal one?


function add(x) {
// Only change code below this line
return (y)=>{
  return (z)=>{
    return x+y+z
  }
}

// Only change code above this line
}
add(10)(20)(30);

Challenge: Introduction to Currying and Partial Application

Link to the challenge:

I have never used it in any project and I am yet to come across any practical use case. You might find the answers to the following SO question informative. I hope they won’t be too advance.

1 Like

Not very important in JS. In some other languages all functions take one (and only one) argument, in which case currying is literally how functions in the language work, and their syntax is normally designed to support it. JS isn’t like that. Partial application can be very useful, but you don’t necessarily need to use currying to do it (can use .bind)


Edit: example lifted from Wikipedia article on OCaml (I’ve written it using Reason syntax, which is closer to JS, apologies if example doesn’t quite work as the translation from OCaml to Reason is from memory) illustrates it’s behaviour.

Here is a function, sum, that takes a list of integers and adds them up:

let sum = (integers) => List.fold_left ((accumulator, x) => accumulator + x), 0, integers);

This is equivalent to the JavaScript:

let sum = (integers) => integers.reduce((acc, x) => acc + x, 0);

However, with the OCaml version, because functions are all curried, composing them is trivial:

+ is a function (not an operator) which takes two parameters (it behaves like (a, b) => a plus b, with a and b being the numbers on either side of the +). The callback (accumulator, x) => accumulator + x is exactly that, so can just do

let sum = (integers) => List.fold_left(+, 0, integers);

Then we’re passing integers into sum and also to List.fold: sum is a function that takes a list of integers and returns the result of a function that takes the same list of integers, so cut out the middleman and just return a function that takes a list (everything is curried, so if you miss out an argument, it just returns a function that expects that argument):

let sum = List.fold_left(+, 0);

That’s exactly the same as

let sum = (integers) => List.fold_left((accumulator, x) => accumulator + x, 0, integers);

And you call it like sum([1,2,3,4]) regardless of how it’s written, works exactly the same.

It’s as if you could write

let sum = reduce(+, 0);

In JS, and it would work the same as this function:

let sum = (integers) => integers.reduce((acc, x) => acc + x, 0);

You can’t*, because JS works differently, and it’s not really built to take advantage of currying at all.

This is a big generalisation (YMMV), but IME have found that many of the people writing enthusiastically about currying in JS are either coming from a language like Haskell and want to replicate what they’re used to (like when people come to JS from Java/C#/similar and try to apply classical OO principles verbatim), or they’ve just learned about functional programming. In either of those cases, possibly best to not apply the advice they give to literally.


* not quite true: you can, and there are various ways of doing it, but they’re all a bit of a pain and involve rewriting built in functions so they work this way. Here’s one:

// Instead of `+`:
let sum = (a, b) => a + b;

let reduce = (callback, initialValue, array) => {
  if (array === undefined) {
    // Only two arguments passed, return a function:
    return (arr) => arr.reduce(callback, initialValue);
  } else {
    // Three arguments passed, run reduce and return a value:
    return array.reduce(callback, initialValue);
  }
};

let sum = reduce(add, 0);
1 Like

I also can’t recall a time that I’ve used currying with JS in the wild but I suspect once the pipeline operator is added to JS (looks like this: |>) we’ll see a bit more of it. There’s also a wave of functional programming taking off too which might increase the popularity of it over time.

As far as I know, people who use currying in their apps are usually using libraries like RxJS or Rambda or something along those lines that help you build your app using functional or reactive programming concepts.

There’s a pretty good article on currying, partial application and point free style which all kinda go hand-in-hand: Curry and Function Composition. Note: This is part of the “Composing… | by Eric Elliott | JavaScript Scene | Medium

My understanding is that the |> operator should remove the need for the custom pipe function used in the article

1 Like

I think this is what i didn’t understand at all, so that’s why its usefull. Thanks! Now I will have to think when it would happen, but it’s good to know i’m not missing too much. Thanks again!

I think this library was using it:

this google map package (outdated):

https://tomchentw.github.io/react-google-maps/

Currying has actual use in wild javascript. In order to notice them, you just have to look past the technical description, which relates to languages that only allow single argument functions. Instead look at the concept: a function that takes arguments, returns another function, delaying or partially applying logic.

So higher order functions, thunks, etc use the same concept as currying, with minor variations and use cases.

Here’s redux-thunk, a popular library for handling async actions in redux:

function makeASandwichWithFavoriteSauce(forPerson) {
 
  // Invert control!
  // Return a function that accepts `dispatch` so we can dispatch later.
  // Thunk middleware knows how to turn thunk async actions into actions.

  // you can even do other logic here using forPerson. For instance, 
  // modifying the shape into what the api expects. 
 
  return function (dispatch) {
    return fetchFavoriteSauce(forPerson).then(
      sauce => dispatch(makeASandwich(forPerson, sauce)),
      error => dispatch(apologize('The Sandwich Shop', forPerson, error))
    );
  };
}

So they’re useful to know for when you need them, just like design patterns. Because if all you have is a hammer, every problem looks like a nail.