# High order functions: What's the benefit returning a function compared to a value?

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];
};
``````
• Where is `p` defined in the second snippet? Jun 15, 2017 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. Jun 15, 2017 at 4:47

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))
``````

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.

• 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). Jun 18, 2017 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. Jun 18, 2017 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. Jun 18, 2017 at 14:56
• @4castle still sounds being first-class is a poor definition of the difference between a closure and a method. Jun 18, 2017 at 14:58