1

In order words, what's the advantage of writing this:

Listing 1

var sortBy = function sortBy(p) {
  return function (a, b) {
    return a[p] > b[p];
  };
};

Compared to this?

Listing 2

var sortBy = function sortBy(p, a, b) {
  return a[p] > b[p];
};

Reference.

  • Where is p defined in the second snippet? – Samuel Jun 15 '17 at 2:15
  • Note that most languages only allow "currying" when the code is factored ala listing 1. Few languages allow currying of arbitrary arguments, but were that the case, you could still curry using listing 2. Under the covers the language would do insert something extra for implementation of such currying. – Erik Eidt Jun 15 '17 at 4:47
6

In the first listing you can partially apply sortBy, in the second you cannot. The advantage of partially applying this function is that you can decouple the dependency of which key to sort by from usages of the sort function. See this question for a more complete description of the advantages of currying.

For example:

const sortByName = sortBy("name")
const a = { name: "aaron" }
const b = { name: "billy" }
const c = { name: "charlie" }
sortByName(a, b) // true
sortByName(b, c) // true

This is useful if you need a binary function. For example Array.prototype.sort() takes a binary function as an argument. You could do something like this (if your sort function was implemented according to the spec):

[a, b, c].sort(sortByName)

but with listing 2 you would have to do something like:

[a, b, c].sort((left, right) => sortBy("name", left, right))
|improve this answer|||||
1

Well now, you're asking two different questions.

What's the benefit returning a function compared to a value? Functions can do things. Values just sit there being things. Unless of course the value is a function.

With listing 1 you can say sortBy(0)(x, y) With listing 2 you have to say sortBy(0, x, y)

Things get fun with listing 1 when you say s = sortBy(0) because now you can say s(x,y) or s(y,z). It's remembered the 0 so you don't have to pass it when you call s. That means the benefit is that you can know these values at different times. You don't have to shove them all in at once.

What you've got hold of there in listing 1 is a little thing called a closure. It's almost the same as an object. The first call acts like a constructor. The second is call is like a method call. The difference is that closures only have one method. So you don't have to know it's name. You give it a name and just throw another () after it.

Of course the functional people hate to hear them called methods. It's not a method it's a closure that "has access to it's enclosing lexical scope". Feh, it's a fancy way to say the vars outside of the inner function the same way a method has access to instance member vars. In this case it's the p that was passed in.

Unlike with objects you get to decide what the method, sorry, closure, is called.

|improve this answer|||||
  • The main difference between a closure and a method is that a method cannot be a first-class value. A method is like a weak form of closure, because a closure can itself be used as the constructor of another closure. The nesting of environments can go farther than 1 level. A better analogy would perhaps be an inner class (although inner classes are themselves closures, so it's not really an analogy, but a tautology). – 4castle Jun 18 '17 at 14:22
  • @4castle a methods status as first-class is a language choice not part of the definition of a method. While Java forces you to work with the fact that only objects are first class Javascript certainly doesn't. Javascript has methods. They use the this keyword just fine. And they are certainly first-class. – candied_orange Jun 18 '17 at 14:48
  • JavaScript's methods are first-class only if you bind a this value. Otherwise they cannot be used as a parameter without evaluating them to a function. – 4castle Jun 18 '17 at 14:56
  • @4castle still sounds being first-class is a poor definition of the difference between a closure and a method. – candied_orange Jun 18 '17 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.