8

What does double arrow parameters mean in the following code?

const update = x => y => {
   // Do something with x and y
}

How is it different compared to the following?

const update = (x, y) => {
   // Do something with x and y
}

Thanks!

glennsl
  • 28,186
  • 12
  • 57
  • 75
His
  • 5,891
  • 15
  • 61
  • 82
  • 1
    These are closures forming a curried function. –  Sep 22 '17 at 13:01
  • 1
    What's the difference between a function that takes two arguments, and a function that takes an argument, and returns another function that takes another argument? – Thomas Sep 22 '17 at 13:03

4 Answers4

11

Let's rewrite them "old style", the first one is:

const update = function (x) {
  return function(y) {
    // Do something with x and y
  };
};

While the second one is:

const update = function (x, y) {
  // Do something with x and y
};

So as you can see they are quite different, the first returns an "intermediate" function, while the second is a single function with two parameters.

Matteo Tassinari
  • 18,121
  • 8
  • 60
  • 81
  • Would you please explain in what use case will I want to use the first one (i.e. function returning a function)? I'm new to Javascript and all. Thanks. – His Sep 22 '17 at 13:02
  • You'd use the first when you want to create a callback, for later use, already bound to the first parameter (`x`); while you'd use the second one to immediately use both parameters (`x` and `y`). – Matteo Tassinari Sep 22 '17 at 13:06
  • 1
    See also @glennsl answer. – Matteo Tassinari Sep 22 '17 at 13:08
7

There's nothing special about "double arrow parameters", this is just one arrow function returning another, and can be extended for as many arguments as you'd like. It's a technique called "currying".

From Wikipedia:

In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument.

The benefit of this is that it makes it easier to partially apply and compose functions, which is useful for some styles of functional programming.

Example

Let's say you have a function add which takes two numbers and adds them together, which you might traditionally write like this:

const add = (a, b) => a + b;

Now let's say you have an array of numbers and want to add 2 to all of them. Using map and the function above, you can do it like this:

[1, 2, 3].map(x => add(2, x));

However, if the function had been in curried form, you wouldn't need to wrap the call to add in another arrow function just to adapt the function to what map expects. Instead you could just do this:

const add = a => b => a + b;
[1, 2, 3].map(add(2));

This is of course a trivial and rather contrived example, but it shows the essence of it. Making it easier to partially apply functions also makes it more practical to write small and flexible functions that can be composed together, which then enables a much more "functional" style of programming.

glennsl
  • 28,186
  • 12
  • 57
  • 75
  • 1
    With currying you abstract over arity, because if every function always expects one argument, arity doesn't matter anymore. –  Sep 22 '17 at 14:45
2

That are called arrow functions, it the new format for functions presented by ES6, in the first example

const update = x => y => {
   // Do something with x and y
}

can be traduced to

 var update = function (x){
        return function (y){
                 // Do something with x and y..
           }
    }

in ES5, and is a function that returns a function is totally different than

const update = function (x, y) {
  // Do something with x and y
};
Renzo Calla
  • 7,486
  • 2
  • 22
  • 37
2

The syntax PARAM => EXPR represents a function that takes a parameter PARAM and whose body is { return EXPR; }. It is itself an expression, so it can be used as the EXPR of other functions:

x => y => { ... }

parses as

x => (y => { ... })

which is the same as

x => { return y => { ... }; }
melpomene
  • 84,125
  • 8
  • 85
  • 148