Better understanding higher order functions - helpful resources

Part of the definition of a HOF is a function that “returns a function.” Can someone please give me an example of a function returning another function? Codecademy doesn’t give one. And whenever I try to return a function, it usually just returns the word “function” in brackets. For instance, check out this code:

const higherOrder = x => {
  return function(x) {
    x + 1;
  }
}

console.log(higherOrder(2));
// prints: [Function]

Here, I expected it to print 3 (after all, 2 + 1 = 3). But instead, it just prints the word “function” in brackets. Why isn’t it working?

Strangely, here’s some other code I tested, which works as expected:

const multiplyByTwo = x => x * 2;

const higherOrder2 = (func, argument) => {
  return func(argument);
}

console.log(higherOrder2(multiplyByTwo, 4));
// prints: 8

How come this prints 8, whereas the first example just prints [function]? Also, is this 2nd code snippet a good example of “a function that returns a function”? Just want to make sure I understand that concept.

The parameter of the returned function cannot be the same as the factory parameter.

I really appreciate your reply! I’m still a bit confused, though. I tried rewriting the code a couple different ways, and it still produces the same result.

Here’s the first way:

const higherOrder = x => {
  return function(y) {
    y + 1;
  }
}

console.log(higherOrder(2));
// prints: [Function]

Here’s the second way:

const higherOrder = x => {
  return function() {
    x + 1;
  }
}

console.log(higherOrder(2));
// prints: [Function]

So I’m still confused as to how to properly return a function. I just watched a YouTube video in which someone returns a function (and it worked), but most of the time I do it, it just returns [function] and I can’t figure out what makes it work correctly or not. What would be the correct way to write this code so that it works how I expect? I’m expecting the anonymous function to run, so that the value of x + 1 is returned (in this case, 3).

I realize I could do without the inner function altogether, but I’m trying to wrap my head around the concept of returning a function.

The output is correct. We cannot log the function, but invoke it with an argument for y.

Consider the equation for slope, the ratio of rise over run of a straight line one a coordinate plane.

y = mx + b

m is the slope
b is the vector distance from the x-axis above the origin. (The origin is where the two axes cross, (0, 0).)

For any value x there is a corresponding value for y which is a point on the coordinate plane.

Enough about the math. Let’s put this into action…

const slope = function (m, b) {
  return x => m * x + b
}

Notice how the factory parameters are embedded in the returned function. Now all that function needs is a value for x.

Given a slope of 2 and a y-intercept of 2 we can produce a function that will describe the line by the points on the graph.

line = slope(2, 2)
y1 = line(2)
y2 = line(5)

console.log(`(2, ${y1}) - (5, ${y2})`)  // (2, 6) - (5,  12)

Thanks so much for your detailed reply! I’m just trying to wrap my head around it. Here are some questions I have.

First, you wrote:

const slope = function (m, b) {
  return x => m * x + b
}

Would that be the same as writing:

const slope = function (m, b) {
  return function(x) {
    m * x + b
    }
}

Second, I’m trying to understand what’s happening at the end of your post – for instance, I see what you did with line (you assigned it the result of invoking slope with 2 and 2 as arguments). But what’s going on with:

y1 = line(2)
y2 = line(5)

Where are the numbers 2 and 5 going? What’s happening with them? If line is equal to slope(2, 2), I don’t see how there’s any way for the variable line to accept arguments.

Lastly (and this is my main question), I still don’t understand the concept of returning a function. For instance, I tested this code:

const slope = function (m, b) {
  return x => m * x + b
}

line = slope(2, 2)
y1 = line(2)
y2 = line(5)

console.log(line);
// prints [Function]

It still just prints [Function]. It seems like no matter what, if you have functionA that returns functionB, then whenever you invoke functionA, it just returns the word [Function]. How is that useful? How do we get it to return the RESULT of invoking functionB, rather than just returning the word [Function]? Am I missing something obvious?

Thanks again for your help, mtf!

1 Like

Yes, they are both the same function expression. The one is just slightly more concise. We can even write it like this,

const slope = (m, b) => x => m * x + b

All are returning a function.

Those are the values for x we pass into our line function. Recall that the line function was returned by the slope function with embedded constants, 2 for slope, and 2 for y-intercept.

y1 = 2 * 2 + 2
y2 = 2 * 5 + 2
     m   x   b

That is only logging the reference, not the invocation.

console.log(line.toString())

//  x => m * x + b

Like we did above, assign it to a variable, in this case, y1 and y2 in two calls.

So I just wanted to share my process for figuring out this exercise. Thanks to those that posted articles and videos that had further explanations of how things work. Those were definitely instrumental in getting me to the finish line on this part of the course.

tl;dr, I had a really hard time visualizing what was happening with the code. I highlight my process starting on line 38 of my github code posted below. There are comments mixed in which hopefully explain things in a clear fashion. I’m a complete beginner so if a more experienced user out there finds issues within my code, please correct me.

codecademywork/callbackFunctions at main · peptobylsma/codecademywork (github.com)

The link cannot be reached. Is there a Share URL?

I had my repository set as private. Sorry about that. Try again - let me know if it doesn’t work.

1 Like

@tag4711444728 Thank you very much for that YouTube recommendation. I found it very helpful!